find_or_initialize_byとfind_or_create_byがデータ作成時に便利というのはよく聞きます。
ただ最初は違いなど気にせず使うことも多いと思うので、さらっと違いと使い方を書いてみました!
最初に結論から言いますとfind_or_initialize_byとfind_or_create_byの違いは
新規作成して保存するorしないです!
| method名 | 役割 |
|---|---|
| find_or_initialize_by | 新規作成して保存はしない |
| find_or_create_by | 新規作成後、保存 |
ソースコードは↓です(本家rails/githubより)。
find_or_initialize_by
def find_or_initialize_by(attributes, &block)
find_by(attributes) || new(attributes, &block)
end
→引数の条件に該当するデータがあればそれを返しfind_by(attributes)、そうでなければ新しくインスタンスnew(attributes, &block)を作成します。
find_or_create_by
def find_or_create_by(attributes, &block)
find_by(attributes) || create(attributes, &block)
end
→引数の条件に該当するデータがあればそれを返すfind_by(attributes)、なければ新規作成create(attributes, &block)します。
後半のnewとcreateが違いますね。
使い道
find_or_initialize_byは処理を追加することができます。
# ex.市町村のマスターデータを更新する
cities = City.find_or_initialize_by(name: '東京')
if cities.new_record? # 新規データなら保存
cities.save!
end
さらに、追加で情報追加したい時なんかはupdate_attributesを使っています。
cities = City.find_or_initialize_by(name: '東京')
if cities.new_record?
cities.update_attributes!(romaji: 'tokyo') # ローマ字データ追加
end
他にもoauthでユーザー登録する時やマスターデータの一斉作成・更新にも便利らしい。