Torihaji's Growth Diary

Little by little, no hurry.

Rails の buildとnewの違い

はじめに

そういえば意外にわかってなかったことを書き連ねていきます

最初は動くものを作る!というモチベで全速力で駆け抜けていたため

最近いざコードを読んでいって「おや?」と思うことが増えてきました。

そうした不足分を都度補っていこうかと。

build と new の違い

同じ点

どちらもオブジェクトを「未保存の状態」でインスタンス化する。

例: Tweet.new(...), TweetImage.new(...) → まだDBには書き込まれない。

主な違い

関連キーを自動セット してくれる

ActiveRecord の has_many / has_one などの関連でよく使うメソッド名が build

tweet = current_user.tweets.build(content: "hello")

これは内部的には Tweet.new(...) とほぼ同様、

has_many :tweets の関連に対して current_user.tweets.new(...) も同様に使えるが、

Railsのコード上では build のほうが「関連から生成している」ことが明確になる。

Railsコミュニティでは、「関連からのインスタンス化」は build を使うことが多い。

単純にモデルを直接newしたいときは Model.new を使う。

build (関連経由)

user.tweets.build(content: "Hello!") 
# => #<Tweet id: nil, content: "Hello!", user_id: user.id, ...>`

new (モデル直接)

Tweet.new(content: "Hello!", user_id: user.id)
# => #<Tweet id: nil, content: "Hello!", user_id: user.id, ...>

結論

build はリレーション(association)を使ったオブジェクト生成のための書き方で、内部的にほぼ new と同じ。

使い分けとしては「関連経由でnewするなら build」、「単独なら new」が一般的なRails慣習。

機能的にはほとんど等価、関連オブジェクトを作る意図を明確化できる点で build が好まれる傾向。