リレーション関連がうまく使いこなせていないので、railsによるアジャイルwebアプリケーション開発を読み返してみた。勉強になったことをメモメモ。
テーブル情報の取得
下記のようなマイグレーションでpeopleテーブルが定義されているとして、
create_table :people do |t| t.string :name t.integer :age t.boolean :auth end
- Person.columun_namesでカラムの名前を配列で取得できる。(クラスメソッド)
- Person.column_hash["name"]のようにすると、Personのname列の情報(デフォルト値とか)を取得できる。*1
- person.attribute_namesで属性の名前の配列が取得できる。(オブジェクトメソッド)
person.age_before_type_cast
のように、属性名に_before_type_castをつけるとデータベースの値をそのまま取得する。(この場合は結果は特に変わらない)
データベースの値を条件判定に使用するときに気をつけること
下記のように、booleanの列を直接条件判定に使うのはよくないらしい。
if person.auth # 処理 end
理由は、DBに入っている値を直接使うと、falseのつもりで設定した値がtrueと解釈されることがあるから。*2このように、列の名前の後ろに?を付けてあげると良いらしい。
if person.auth? # 処理 end
このようにすると、DBに下記の値が格納されていればfalseとするみたい。
- 0
- "0"
- "f"
- "false"
- ""
- nil
- false
create
createの引数に、属性ハッシュの配列を渡すことで、複数のオブジェクトを保存できる。
Person.create([{:name => "willnet"}, {:name => "netwillnet"}])
findメソッドのプレースホルダ指定方法4つ。
その1
一番ベーシック(だと個人的に思っている)やり方。
Person.find(:all, :conditions => ["name = ?", name])
その3
その2改良版。paramsを条件に渡すやり方。
Person.find(:all, :conditions => ["name = :name", params[:person])
その4
究極版?paramsだけで条件文を作ってくれる。
Person.find(:all, :conditions => params[:person])
これまで、その1しか使ってなかった><その3が使えそうかな。その4はすごく簡潔な表現だけど、使いどころを気をつけないといけないからあんまり使いたくないな。
動的ファインダ
People.find_by_nameのようなものを動的ファインダというらしい。よく使うけど名前は知らなかった。
変わり種な動的ファインダ
下記のような動的ファインダもあるみたい。
Person.find_or_initialize_by_name("willnet")
動作はこれと一緒
Person.find_by_name("willnet") || Person.new(:name => "willnet")
createもある
Person.find_or_create_by_name("willnet)
動作は一緒
Person.find_by_name("willnet") || Person.create(:name => "willnet")
うーん。確かに短くなるけど使うかなあ?
既存の行の更新
基本的にはsaveメソッドだけ使えれば事足りるのだけど、コードを短くする手法がいくつかある。
save
ノーマルバージョン。
willnet = People.find(1) willnet.name = "netwillnet" willnet.save
update_attributes
値の変更とsaveを同時に。
willnet = People.find(1) willnet.update_attributes(:name => "netwillnet")
update
値の取得と変更とsaveを同時に
People.update(1, :name => "netwillnet")
行の削除
delete系とdestroy系の2つのメソッドがある。違いはコールバックや検証機能を経由するかしないか。
deleteは検証やコールバックをせずにいきなり削除する。なので普通はdestroyを使うのがよい。
delete例
Person.delete(1) Person.delete_all(["age > ?", 20])
destroy例
willnet = Person.find(1) willnet.destroy Person.destroy(1) Person.destroy_all(["age > ?", 20])
今日はここまで
思ったより時間がかかってしまった。リレーションまでたどり着けてない><
参考
RailsによるアジャイルWebアプリケーション開発 第2版
- 作者: Dave Thomas,David Heinemeier Hansson,Leon Breedt,Mike Clark,Andreas Schwarz,James Duncan Davidson,Justin Gehtland,前田修吾
- 出版社/メーカー: オーム社
- 発売日: 2007/10/26
- メディア: 大型本
- 購入: 18人 クリック: 300回
- この商品を含むブログ (138件) を見る