diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 5fccf3a43d..4ed78bcbef 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -8,7 +8,8 @@ module ActiveRecord JoinOperation = Struct.new(:relation, :join_class, :on) MULTI_VALUE_METHODS = [:includes, :eager_load, :preload, :select, :group, - :order, :joins, :where, :having, :bind, :references] + :order, :joins, :where, :having, :bind, :references, + :extending] SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reordering, :reverse_order, :uniq, :create_with] @@ -18,7 +19,7 @@ module ActiveRecord include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation attr_reader :table, :klass, :loaded - attr_accessor :extensions, :default_scoped + attr_accessor :default_scoped alias :loaded? :loaded alias :default_scoped? :default_scoped @@ -31,7 +32,7 @@ module ActiveRecord SINGLE_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_value", nil)} MULTI_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_values", [])} - @extensions = [] + @create_with_value = {} end diff --git a/activerecord/lib/active_record/relation/merger.rb b/activerecord/lib/active_record/relation/merger.rb index 77bfe82a83..b6fdb23066 100644 --- a/activerecord/lib/active_record/relation/merger.rb +++ b/activerecord/lib/active_record/relation/merger.rb @@ -26,7 +26,6 @@ module ActiveRecord hash = {} Relation::MULTI_VALUE_METHODS.map { |name| hash[name] = other.send("#{name}_values") } Relation::SINGLE_VALUE_METHODS.map { |name| hash[name] = other.send("#{name}_value") } - hash[:extensions] = other.extensions hash end end @@ -73,8 +72,7 @@ module ActiveRecord relation.order_values += values[:order] end - # Apply scope extension modules - relation.send :apply_modules, values[:extensions] if values[:extensions] + relation.extend(*values[:extending]) unless values[:extending].blank? end def merge_single_values diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 10492165fb..eaa3ddaec8 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -10,7 +10,9 @@ module ActiveRecord :where_values, :having_values, :bind_values, :limit_value, :offset_value, :lock_value, :readonly_value, :create_with_value, :from_value, :reordering_value, :reverse_order_value, - :uniq_value, :references_values + :uniq_value, :references_values, :extending_values + + alias extensions extending_values def includes(*args) args.empty? ? self : clone.includes!(*args) @@ -353,7 +355,9 @@ module ActiveRecord def extending!(*modules, &block) modules << Module.new(&block) if block_given? - self.send(:apply_modules, modules.flatten) + self.extending_values = modules.flatten + extend(*extending_values) + self end @@ -494,13 +498,6 @@ module ActiveRecord end end - def apply_modules(modules) - unless modules.empty? - @extensions += modules - modules.each {|extension| extend(extension) } - end - end - def reverse_sql_order(order_query) order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty? diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index a53ee01afa..a365b5723b 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -40,8 +40,7 @@ module ActiveRecord result.send(:"#{method}_value=", send(:"#{method}_value")) end - # Apply scope extension modules - result.send(:apply_modules, extensions) + result.extend(*extending_values) if extending_values.any? result end @@ -65,8 +64,7 @@ module ActiveRecord result.send(:"#{method}_value=", send(:"#{method}_value")) end - # Apply scope extension modules - result.send(:apply_modules, extensions) + result.extend(*extending_values) if extending_values.any? result end diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index c1063698bd..fdd8e2112e 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -156,7 +156,7 @@ module ActiveRecord @relation ||= Relation.new :a, :b end - (Relation::MULTI_VALUE_METHODS - [:references]).each do |method| + (Relation::MULTI_VALUE_METHODS - [:references, :extending]).each do |method| test "##{method}!" do assert relation.public_send("#{method}!", :foo).equal?(relation) assert_equal [:foo], relation.public_send("#{method}_values") @@ -168,6 +168,14 @@ module ActiveRecord assert relation.references_values.include?('foo') end + test 'extending!' do + mod = Module.new + + assert relation.extending!(mod).equal?(relation) + assert [mod], relation.extending_values + assert relation.is_a?(mod) + end + (Relation::SINGLE_VALUE_METHODS - [:lock, :reordering, :reverse_order, :create_with]).each do |method| test "##{method}!" do assert relation.public_send("#{method}!", :foo).equal?(relation) @@ -195,13 +203,6 @@ module ActiveRecord assert !relation.reverse_order_value end - test 'extending!' do - mod = Module.new - - assert relation.extending!(mod).equal?(relation) - assert relation.is_a?(mod) - end - test 'create_with!' do assert relation.create_with!(foo: 'bar').equal?(relation) assert_equal({foo: 'bar'}, relation.create_with_value)