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?
|
if match.finder?
|
||||||
find_by_attributes(match, attributes, *args)
|
find_by_attributes(match, attributes, *args)
|
||||||
|
elsif match.instantiator?
|
||||||
|
find_or_instantiator_by_attributes(match, attributes, *args, &block)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
super
|
super
|
||||||
|
@ -159,6 +161,27 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
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)
|
def create_new_relation(relation, readonly = @readonly, preload = @associations_to_preload, eager_load = @eager_load_associations)
|
||||||
Relation.new(@klass, relation, readonly, preload, eager_load)
|
Relation.new(@klass, relation, readonly, preload, eager_load)
|
||||||
end
|
end
|
||||||
|
|
|
@ -254,5 +254,26 @@ class RelationTest < ActiveRecord::TestCase
|
||||||
assert_kind_of Array, davids
|
assert_kind_of Array, davids
|
||||||
assert_equal [authors(:david)], davids
|
assert_equal [authors(:david)], davids
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue