その他

【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
酒井 駿
名古屋工業大学大学院卒業後、豊田合成(株)で品質管理を経験し、その後スタートアップ・マネーフォワードを経て、2024年11月に株式会社EGGHEAD創業。 製造業とエンジニアリング、両方の現場の知見を活かし、製造業における生成AIを活用した業務改善やシステム開発を支援します。