31
15

More than 5 years have passed since last update.

RecordをbuildしようとしたらNoMethodErrorで怒られた人へ

Posted at

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

一回通った方法を機械的にリピートしてると思わぬところでコケたりするんだなぁ。

31
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
15