TL;DR
has_one
関連のモデルに対しては build
は使えないので build_xxx
を使う。
実例
Rails 4.2にて
shop.rb
class Shop < ActiveRecord::Base
has_one :owner
has_many :products
end
[1] pry(main)> shop = Shop.last
[2] pry(main)> shop.products.build
=> #<Product:0x007fbc9a1468e8 id: nil, name: nil, price: nil, created_at: nil, updated_at: nil>
[3] pry(main)> shop.owner.build
NoMethodError: undefined method 'build' for nil:NilClass
[4] pry(main)> shop.build_owner
=> #<Owner:0x007fbc7a8da840 id: nil, name: nil, created_at: nil, updated_at: nil>
原因
has_many
関連のModelに対してRecordを呼び出した場合、Recordがなくても、空の ActiveRecord_Associations_CollectionProxy
が返る。そこには build
が定義されている。(http://api.rubyonrails.org/classes/ActiveRecord/Associations/CollectionProxy.html#method-i-build)
しかし、 has_one
関連のModelに対してRecordを呼び出した場合、Recordがないと返ってくるのは nil
であり、当然 build
の定義はない。
[8] pry(main)> shop.products
=> []
[9] pry(main)> shop.products.class
=> Product::ActiveRecord_Associations_CollectionProxy
[10] pry(main)> shop.owner
=> nil
一回通った方法を機械的にリピートしてると思わぬところでコケたりするんだなぁ。