Help us understand the problem. What is going on with this article?

find_or_initialize_byとfind_or_create_byの違いとは?

find_or_initialize_byfind_or_create_byがデータ作成時に便利というのはよく聞きます。
ただ最初は違いなど気にせず使うことも多いと思うので、さらっと違いと使い方を書いてみました!

最初に結論から言いますとfind_or_initialize_byfind_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)します。

後半のnewcreateが違いますね。

使い道

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でユーザー登録する時やマスターデータの一斉作成・更新にも便利らしい。

参考リンク

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away