Rails4以上で使える `find_or_create_by` `find_or_initialize_by` が便利

More than 3 years have passed since last update.

たまたまAPIリファレンス見ていたら気づいた!

find_or_create_byfind_or_initialize_by

http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-find_or_create_by

メソッド名その名の通りの挙動になると想像できると思うが、引数に渡した条件により、フィルタリングされ、ブロックにより必要な値をセットすることで createinitialize する時の初期値が設定できる。


サンプル

# first_nameが abc のデータがあれば find される

# first_nameが abc のデータが無ければ、first_name: 'abc'、last_name: "123" が入ったユーザがcreateされる。
User.find_or_create_by(first_name: 'abc') do |user|
user.last_name = '123'
end

# メソッドの引数に複数を設定するとfind_by時の条件が AND での複数条件検索となる。
User.find_or_create_by(first_name: 'abc', group_id: 3) do |user|
user.last_name = '123'
end



ユースケース


oauthで認証時にユーザ新規登録なのか、既存ユーザなのか判定する処理とかでうまく使えそう

oauth認証で帰ってくるコールバックのコントローラから以下の find_or_create_with_oauth メソッドを呼び出す。


oauthのサンプル

# 動作するか未保証

class User < ActiveRecord::Base
def self.find_or_create_with_oauth(oauth)
User.find_or_create_by(uid: oauth['uid']) do |user|
user.name = oauth['name']
user.provider = oauth['provider']
user.uid = oauth['uid']
end
end
end

以上。