たまたまAPIリファレンス見ていたら気づいた!
find_or_create_by
と find_or_initialize_by
http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-find_or_create_by
メソッド名その名の通りの挙動になると想像できると思うが、引数に渡した条件により、フィルタリングされ、ブロックにより必要な値をセットすることで create
や initialize
する時の初期値が設定できる。
サンプル
# 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
以上。