From a68165833a7ba50a1e3d731afe8934d19e3ced99 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Mon, 4 Jan 2010 03:50:16 +0530 Subject: [PATCH] Add Relation#create_with to explictily specify create scope --- activerecord/lib/active_record/relation.rb | 16 +++++++++------- .../lib/active_record/relation/query_methods.rb | 4 ++++ .../lib/active_record/relation/spawn_methods.rb | 10 ++++++++++ activerecord/test/cases/relations_test.rb | 8 ++++++++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 6b9925d4e7..487b54f27d 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -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 diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 525a9cb365..5d7bf0b7bc 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -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)) diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index a637e97155..4ecee8c634 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -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) diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index f895f8b8d2..195889f1df 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -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