すごく違和感のある挙動に遭遇したのでメモ。
例えば、以下のようなhas_manyな関係を持つ2つのクラスがある。
class Parent < ActiveRecord::Base
has_many :children
accepts_nested_attributes_for :children
end
class Child < ActiveRecord::Base
belongs_to :parent
end
Formからネストしたパラメータが渡ってきた場合など、以下のようにする場合が多いと思う。
親データ1件と、その子データ3件を同時に作成する場合。
この場合、p.children.empty?はtrueを返すが、実際にp.childrenを出力すると、期待通りChildクラスのインスタンスが3つ入っている。
しかも、p.childrenを一度出力した後に再度p.children.empty?を呼ぶとfalseが帰ってくるという不思議仕様。
p = Parent.new({
name: 'parent',
children: [
{ name: 'child1' },
{ name: 'child2' },
{ name: 'child3' },
]
})
p.children.empty?
=> true
p.children
=>[#<Child name:'child1'>,#<Child name:'child2'>,#<Child name:'child3'>]
p.children.empty?
=> false
ちなみに、上記とデータ構造は全く同じだが、一度Parentのインスタンスを作成してから、Childを1つずつ追加していくと、p.children.empty?はきちんとfalseを返し、p.childrenの出力も期待通りChildクラスのインスタンスが3つ入っている。
p = Parent.new({ name: 'parent' })
p.children << Child.new({ name: 'child1' })
p.children << Child.new({ name: 'child2' })
p.children << Child.new({ name: 'child3' })
p.children.empty?
=> false
p.children
=>[#<Child name:'child1'>,#<Child name:'child2'>,#<Child name:'child3'>]
これってlazy loading的な何かがあるので仕方ないですよとか言われたら納得しちゃうかもしれないけど単純にバグな気がするのでちょっと頑張る