Ruby on Rails

【Rails】buildメソッドについて

今回は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.addressnilが返るからです。

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_モデル名を使う

まとめ

以上になります。関連によって書き方が違って最初は混乱するとは思いますが、この機会にぜひ覚えておきましょう。

ABOUT ME
sakai
三重出身の28歳。前職はメーカーで働いていて、プログラミングスクールに通って未経験からWeb業界に転職しました。Railsをメインで使っていて、AWSも少しできます。音楽を聞くこととYoutubeを見るのが好きです。最近はへきトラ劇場にハマってます