Skip to content
This repository
Browse code

fix association :extend option

  • Loading branch information...
commit 7fa9cb58c6e3b9311f0306173c48874ace7a6b04 1 parent 8baaa45
Jon Leighton jonleighton authored
8 activerecord/lib/active_record/associations/association_scope.rb
@@ -15,9 +15,7 @@ def initialize(association)
15 15
16 16 def scope
17 17 scope = klass.unscoped
18   - scope.extending!(*Array(options[:extend]))
19 18 scope.merge! eval_scope(klass, reflection.scope) if reflection.scope
20   -
21 19 add_constraints(scope)
22 20 end
23 21
@@ -120,10 +118,8 @@ def table_name_for(reflection)
120 118 end
121 119
122 120 def eval_scope(klass, scope)
123   - return scope if scope.is_a?(Relation)
124   -
125   - if scope.arity == 0
126   - klass.unscoped.instance_exec(&scope)
  121 + if scope.is_a?(Relation)
  122 + scope
127 123 else
128 124 klass.unscoped.instance_exec(owner, &scope)
129 125 end
5 activerecord/lib/active_record/associations/builder/association.rb
@@ -23,6 +23,11 @@ def initialize(model, name, scope, options)
23 23 @scope = nil
24 24 @options = scope
25 25 end
  26 +
  27 + if @scope && @scope.arity == 0
  28 + prev_scope = @scope
  29 + @scope = proc { instance_exec(&prev_scope) }
  30 + end
26 31 end
27 32
28 33 def mixin
18 activerecord/lib/active_record/associations/builder/collection_association.rb
@@ -6,7 +6,7 @@ def valid_options
6 6 super + [:table_name, :finder_sql, :counter_sql, :before_add, :after_add, :before_remove, :after_remove]
7 7 end
8 8
9   - attr_reader :block_extension
  9 + attr_reader :block_extension, :extension_module
10 10
11 11 def initialize(*args, &extension)
12 12 super(*args)
@@ -27,18 +27,24 @@ def writable?
27 27 private
28 28
29 29 def wrap_block_extension
30   - options[:extend] = Array(options[:extend])
31   -
32 30 if block_extension
  31 + @extension_module = mod = Module.new(&block_extension)
33 32 silence_warnings do
34   - model.parent.const_set(extension_module_name, Module.new(&block_extension))
  33 + model.parent.const_set(extension_module_name, mod)
  34 + end
  35 +
  36 + prev_scope = @scope
  37 +
  38 + if prev_scope
  39 + @scope = proc { |owner| instance_exec(owner, &prev_scope).extending(mod) }
  40 + else
  41 + @scope = proc { extending(mod) }
35 42 end
36   - options[:extend].push("#{model.parent}::#{extension_module_name}".constantize)
37 43 end
38 44 end
39 45
40 46 def extension_module_name
41   - @extension_module_name ||= "#{model.to_s.demodulize}#{name.to_s.camelize}AssociationExtension"
  47 + @extension_module_name ||= "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension"
42 48 end
43 49
44 50 def define_callback(callback_name)
2  activerecord/lib/active_record/relation/query_methods.rb
@@ -529,7 +529,7 @@ def extending(*modules, &block)
529 529 def extending!(*modules, &block)
530 530 modules << Module.new(&block) if block_given?
531 531
532   - self.extending_values = modules.flatten
  532 + self.extending_values += modules.flatten
533 533 extend(*extending_values) if extending_values.any?
534 534
535 535 self
2  activerecord/test/cases/associations/extension_test.rb
@@ -72,6 +72,6 @@ def test_proxy_association_after_scoped
72 72 def extension_name(model)
73 73 builder = ActiveRecord::Associations::Builder::HasMany.new(model, :association_name, nil, {}) { }
74 74 builder.send(:wrap_block_extension)
75   - builder.options[:extend].first.name
  75 + builder.extension_module.name
76 76 end
77 77 end
7 activerecord/test/cases/relation_test.rb
@@ -191,11 +191,14 @@ def relation
191 191 end
192 192
193 193 test 'extending!' do
194   - mod = Module.new
  194 + mod, mod2 = Module.new, Module.new
195 195
196 196 assert relation.extending!(mod).equal?(relation)
197   - assert [mod], relation.extending_values
  197 + assert_equal [mod], relation.extending_values
198 198 assert relation.is_a?(mod)
  199 +
  200 + relation.extending!(mod2)
  201 + assert_equal [mod, mod2], relation.extending_values
199 202 end
200 203
201 204 test 'extending! with empty args' do

0 comments on commit 7fa9cb5

Please sign in to comment.
Something went wrong with that request. Please try again.