From eb72e62c3042c0df989d951b1d12291395ebdb8e Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Fri, 19 Oct 2012 13:18:47 +0100 Subject: Add Relation#find_or_create_by and friends This is similar to #first_or_create, but slightly different and a nicer API. See the CHANGELOG/docs in the commit. Fixes #7853 --- activerecord/lib/active_record/relation.rb | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'activerecord/lib/active_record/relation.rb') diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index ecce7c703b..d106fceca2 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -133,6 +133,10 @@ module ActiveRecord # # Expects arguments in the same format as +Base.create+. # + # Note that the create will execute within the context of this scope, and that may for example + # affect the result of queries within callbacks. If you don't want this, use the find_or_create_by + # method. + # # ==== Examples # # Find the first user named Penélope or create a new one. # User.where(:first_name => 'Penélope').first_or_create @@ -171,6 +175,28 @@ module ActiveRecord first || new(attributes, &block) end + # Finds the first record with the given attributes, or creates it if one does not exist. + # + # See also first_or_create. + # + # ==== Examples + # # Find the first user named Penélope or create a new one. + # User.find_or_create_by(first_name: 'Penélope') + # # => + def find_or_create_by(attributes, &block) + find_by(attributes) || create(attributes, &block) + end + + # Like find_or_create_by, but calls create! so an exception is raised if the created record is invalid. + def find_or_create_by!(attributes, &block) + find_by(attributes) || create!(attributes, &block) + end + + # Like find_or_create_by, but calls new instead of create. + def find_or_initialize_by(attributes, &block) + find_by(attributes) || new(attributes, &block) + end + # Runs EXPLAIN on the query or queries triggered by this relation and # returns the result as a string. The string is formatted imitating the # ones printed by the database shell. -- cgit v1.2.3