今回はbuildメソッドについて簡単にまとめていきたいと思います。Rubyのバージョンは2.6を想定しています。
サンプルアプリ
今回はイベントを開催でき、またそれに参加することができるアプリをサンプルとします。ER図を下に示します。
buildメソッドとは
buildメソッドはクラスのインスタンスを生成するのに使います。しかし、以下のようにモデルの関連によって記載方法が少し異なってきます。
・1対多の場合(多対多)
・1対1の場合
もぐくん
使い分けないといけないのか
1対多の場合
newメソッドと同様に関連した子クラスのインスタンスを生成しますが、newメソッドと違い直接クラスのインスタンスを作成することはできません。
current_user.tickets.new
=> #<Ticket:0x00007fc815c26610 id: nil, user_id: 1, event_id: nil, comment: nil, created_at: nil, updated_at: nil>
current_user.tickets.build
=> #<Ticket:0x00007fc81550f1d8 id: nil, user_id: 1, event_id: nil, comment: nil, created_at: nil, updated_at: nil>
Ticket.new
=> #<Ticket:0x00007fc816606f18 id: nil, user_id: nil, event_id: nil, comment: nil, created_at: nil, updated_at: nil>
Ticket.build
NoMethodError: undefined method `build' for #<Class:0x00007fc815be2168>
昔は関連した子クラスのインスタンスを生成するときにnewを使うとuser_idに値がセットされなかったみたいで、それの影響で今でも慣習的に関連した小クラスのインスタンスの生成にはbuildを使うようです。
さかい
読みやすさのため、buildメソッドを使いましょう
1対1の場合
アソシエーションが1対1のときには、build_モデル名
という形をとります。まず、先程のような書き方をすると、NoMethodError
となります。これはcurrent_user.address
でnil
が返るからです。
current_user.address.new
NoMethodError: undefined method `new' for nil:NilClass
current_user.address
=> nil
そのため、buildしようとしても同様にNoMethodError
になります。
current_user.address.build
NoMethodError: undefined method `build' for nil:NilClass
新たにインスタンスをつくりたいときにはbuild_モデル名
のメソッドを使います。
current_user.build_address
=> #<Address:0x00007f82c0c84958 id: nil, postcode: nil, address1: nil, address2: nil, user_id: 1, created_at: nil, updated_at: nil>
- 1対多(多対多)のアソシエーションの場合、buildを使う
- 1対1のアソシエーションの場合、build_モデル名を使う
まとめ
以上になります。関連によって書き方が違って最初は混乱するとは思いますが、この機会にぜひ覚えておきましょう。
[…] 【Rails】buildメソッドについて […]
【Rails】buildメソッドについて|Rubinistを目指す新米エンジニアのTECH BLOG
asccbjygqz
sccbjygqz http://www.g2z2ih8016c8lk36t6rf301ml78e2jjjs.org/
[url=http://www.g2z2ih8016c8lk36t6rf301ml78e2jjjs.org/]usccbjygqz[/url]