mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add find_or_create_by_* and find_or_initialize_by_* to relations
This commit is contained in:
parent
8829d6ecc6
commit
d511de0261
2 changed files with 44 additions and 0 deletions
|
@ -142,6 +142,8 @@ module ActiveRecord
|
|||
|
||||
if match.finder?
|
||||
find_by_attributes(match, attributes, *args)
|
||||
elsif match.instantiator?
|
||||
find_or_instantiator_by_attributes(match, attributes, *args, &block)
|
||||
end
|
||||
else
|
||||
super
|
||||
|
@ -159,6 +161,27 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def find_or_instantiator_by_attributes(match, attributes, *args)
|
||||
guard_protected_attributes = false
|
||||
|
||||
attributes_for_create = conditions = attributes.inject({}) {|h, a| h[a] = args[attributes.index(a)]; h}
|
||||
|
||||
if args[0].is_a?(Hash)
|
||||
guard_protected_attributes = true
|
||||
conditions = args[0].with_indifferent_access.slice(*attributes).symbolize_keys
|
||||
end
|
||||
|
||||
record = where(conditions).first
|
||||
|
||||
unless record
|
||||
record = @klass.new { |r| r.send(:attributes=, attributes_for_create, guard_protected_attributes) }
|
||||
yield(record) if block_given?
|
||||
record.save if match.instantiator == :create
|
||||
end
|
||||
|
||||
record
|
||||
end
|
||||
|
||||
def create_new_relation(relation, readonly = @readonly, preload = @associations_to_preload, eager_load = @eager_load_associations)
|
||||
Relation.new(@klass, relation, readonly, preload, eager_load)
|
||||
end
|
||||
|
|
|
@ -254,5 +254,26 @@ class RelationTest < ActiveRecord::TestCase
|
|||
assert_kind_of Array, davids
|
||||
assert_equal [authors(:david)], davids
|
||||
end
|
||||
|
||||
def test_dynamic_find_or_initialize_by_attributes
|
||||
authors = Author.scoped
|
||||
|
||||
lifo = authors.find_or_initialize_by_name('Lifo')
|
||||
assert_equal "Lifo", lifo.name
|
||||
assert lifo.new_record?
|
||||
|
||||
assert_equal authors(:david), authors.find_or_initialize_by_name(:name => 'David')
|
||||
end
|
||||
|
||||
def test_dynamic_find_or_create_by_attributes
|
||||
authors = Author.scoped
|
||||
|
||||
lifo = authors.find_or_create_by_name('Lifo')
|
||||
assert_equal "Lifo", lifo.name
|
||||
assert ! lifo.new_record?
|
||||
|
||||
assert_equal authors(:david), authors.find_or_create_by_name(:name => 'David')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue