後半セッションは次の三つ
そこから ActiveRecord の話し。新機能を意欲的に使おうとすると結構はまったり。
Ruby on Rails 2.3 Release Notes — Ruby on Rails Guidesをみながら
Nested Attributes どうよ
関連オブジェクトを持ってるとき、それらの複数のオブジェクトを一画面で操作する、今までいろいろ頑張る必要があったが、「form_for云々 do |f|」の f の 「f.fields_for云々 do |field|」で関連オブジェクトのフォームが書けるし、save でもそれらを一気に保存できる。
キーワードは accepts_nested_attributes_for。
で、それは
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/nested_attributes.rb にある。上記の事例の様な説明もソースにいろいろ書いてある。同じ所の associations.rb、 autosave_association.rb も :autosave => true だと、この辺が動いて関連するオブジェクトの操作を自動化してる。
エラーとかもね。
日本語化
バリデーションエラーメッセージを日本語化してみる。
config/locales/translation_ja.yml に辞書ファイル作ってやってやるんだが、関連オブジェクト(子)のフィールド名とか翻訳してもらえない。
@errors を見たり。translation_ja.yml の親のパートに、「子の名前アンダースコア子のフィールド名」な翻訳項目を作ってやらないといけない。子の翻訳パートをそのまま追っかけてはくれない。(翻訳が DRY じゃなくなるね)
チケット 2210 のパッチがあるよ(まつださん)
子のバリデーションのスルー
チケット2249 子のバリデーションをしないで保存できてしまうケースがある。危険注意。パッチあり。
attr_protected、attr_accessible
マスアトリビューツでのまとめ更新の場合。
親で attr_accessible を使うとき、子の分も言及してないといけない。
また、「attr_accessible :<親のフィールド>, :<子>_attributs」といった感じで、attributes まで書かないといけない。かっこ悪い。
AssociationProxy
has_many な <子>s のインスタンスは Array と名乗るが AssociationProxy だよね。
「<親のインスタンス>.<子>s << <まだセーブしてない奴>」
って、そのとき INSERT される。
「<親のインスタンス>.<子>s.target << <まだセーブしてない奴>」
だと挿入されない。.target でプロクシの行き先になってる。
associations/association_proxy.rb を読もう。
INSERT を走らせずに子の配列に入れたりできる。コントローラなり謬^でネステッド使っていろいろするときなんか前準備してていつのまにか子のセーブが走るようなことがあったり、その回避
或は set_<アソシエーション名>_target
attachment_fu で添付の画像とかな子要素でなんかいろいろあったよ(まつださん)
Dynamic Scopes
<クラス>.scoped_by_<フィールド名> で、その場でスコープが取れる。scoped_by_ のメソッドチェインも出来る(2.3.1では出来なかった)。
動的にその場で作ってるので、あんまり同じの何度も使うなら、別にスコープ定義していた方が良いかも。
Default Scopes
オーダー_バイとか削除フラグとかデフォルトで付けらるのは良さそう。
でも現状でチケット多数。
組み合わせとかケースによっていろいろあるので危険かも。(あんまりつかわないようにしてる、まつださん)
「デフォルトスコープはネイムドスコープではありません」だからデフォルトスコープをネイムドスコープと組み合わせて使うとなんか変な事がある。
with_exclusive_scope でデフォルトスコープを回避できる、かもしれない。
named_scope 経由で count
アソシエーション経由でネイムドスコープで .count するとちょっとおかしいかも、という事例が報告されてる。時に正しくない SQL を作ってしまう。
チケット 2189