mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add Relation#create_with to explictily specify create scope
This commit is contained in:
parent
a115b5d79a
commit
a68165833a
4 changed files with 31 additions and 7 deletions
|
@ -6,7 +6,7 @@ module ActiveRecord
|
|||
|
||||
attr_reader :relation, :klass
|
||||
attr_writer :readonly, :table
|
||||
attr_accessor :preload_associations, :eager_load_associations, :includes_associations
|
||||
attr_accessor :preload_associations, :eager_load_associations, :includes_associations, :create_with_attributes
|
||||
|
||||
def initialize(klass, relation)
|
||||
@klass, @relation = klass, relation
|
||||
|
@ -124,7 +124,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def reset
|
||||
@first = @last = @create_scope = @to_sql = @order_clause = nil
|
||||
@first = @last = @to_sql = @order_clause = @scope_for_create = nil
|
||||
@records = []
|
||||
self
|
||||
end
|
||||
|
@ -163,13 +163,15 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def with_create_scope
|
||||
@klass.send(:with_scope, :create => create_scope) { yield }
|
||||
@klass.send(:with_scope, :create => scope_for_create) { yield }
|
||||
end
|
||||
|
||||
def create_scope
|
||||
@create_scope ||= wheres.inject({}) do |hash, where|
|
||||
hash[where.operand1.name] = where.operand2.value if where.is_a?(Arel::Predicates::Equality)
|
||||
hash
|
||||
def scope_for_create
|
||||
@scope_for_create ||= begin
|
||||
@create_with_attributes || wheres.inject({}) do |hash, where|
|
||||
hash[where.operand1.name] = where.operand2.value if where.is_a?(Arel::Predicates::Equality)
|
||||
hash
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@ module ActiveRecord
|
|||
spawn.tap {|r| r.readonly = status }
|
||||
end
|
||||
|
||||
def create_with(attributes = {})
|
||||
spawn.tap {|r| r.create_with_attributes = attributes }
|
||||
end
|
||||
|
||||
def select(selects)
|
||||
if selects.present?
|
||||
relation = spawn(@relation.project(selects))
|
||||
|
|
|
@ -6,6 +6,7 @@ module ActiveRecord
|
|||
relation.preload_associations = @preload_associations
|
||||
relation.eager_load_associations = @eager_load_associations
|
||||
relation.includes_associations = @includes_associations
|
||||
relation.create_with_attributes = @create_with_attributes
|
||||
relation.table = table
|
||||
relation
|
||||
end
|
||||
|
@ -32,6 +33,14 @@ module ActiveRecord
|
|||
merged_order = relation_order.present? ? relation_order : order_clause
|
||||
merged_relation = merged_relation.order(merged_order)
|
||||
|
||||
merged_relation.create_with_attributes = @create_with_attributes
|
||||
|
||||
if @create_with_attributes && r.create_with_attributes
|
||||
merged_relation.create_with_attributes = @create_with_attributes.merge(r.create_with_attributes)
|
||||
else
|
||||
merged_relation.create_with_attributes = r.create_with_attributes || @create_with_attributes
|
||||
end
|
||||
|
||||
merged_wheres = @relation.wheres
|
||||
|
||||
r.wheres.each do |w|
|
||||
|
@ -56,6 +65,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
result.readonly = self.readonly unless skips.include?(:readonly)
|
||||
result.create_with_attributes = @create_with_attributes unless skips.include?(:create_with)
|
||||
|
||||
result = result.joins(@relation.joins(@relation)) unless skips.include?(:joins)
|
||||
result = result.group(@relation.groupings) unless skips.include?(:group)
|
||||
|
|
|
@ -545,6 +545,14 @@ class RelationTest < ActiveRecord::TestCase
|
|||
assert_equal 'hen', hen.name
|
||||
end
|
||||
|
||||
def test_explicit_create_scope
|
||||
hens = Bird.where(:name => 'hen')
|
||||
assert_equal 'hen', hens.new.name
|
||||
|
||||
hens = hens.create_with(:name => 'cock')
|
||||
assert_equal 'cock', hens.new.name
|
||||
end
|
||||
|
||||
def test_except
|
||||
relation = Post.where(:author_id => 1).order('id ASC').limit(1)
|
||||
assert_equal [posts(:welcome)], relation.all
|
||||
|
|
Loading…
Reference in a new issue