Skip to content

Commit

Permalink
fix association :extend option
Browse files Browse the repository at this point in the history
  • Loading branch information
jonleighton committed Jul 13, 2012
1 parent 8baaa45 commit 7fa9cb5
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 16 deletions.
Expand Up @@ -15,9 +15,7 @@ def initialize(association)

def scope
scope = klass.unscoped
scope.extending!(*Array(options[:extend]))
scope.merge! eval_scope(klass, reflection.scope) if reflection.scope

add_constraints(scope)
end

Expand Down Expand Up @@ -120,10 +118,8 @@ def table_name_for(reflection)
end

def eval_scope(klass, scope)
return scope if scope.is_a?(Relation)

if scope.arity == 0
klass.unscoped.instance_exec(&scope)
if scope.is_a?(Relation)
scope
else
klass.unscoped.instance_exec(owner, &scope)
end
Expand Down
Expand Up @@ -23,6 +23,11 @@ def initialize(model, name, scope, options)
@scope = nil
@options = scope
end

if @scope && @scope.arity == 0
prev_scope = @scope
@scope = proc { instance_exec(&prev_scope) }
end
end

def mixin
Expand Down
Expand Up @@ -6,7 +6,7 @@ def valid_options
super + [:table_name, :finder_sql, :counter_sql, :before_add, :after_add, :before_remove, :after_remove]
end

attr_reader :block_extension
attr_reader :block_extension, :extension_module

def initialize(*args, &extension)
super(*args)
Expand All @@ -27,18 +27,24 @@ def writable?
private

def wrap_block_extension
options[:extend] = Array(options[:extend])

if block_extension
@extension_module = mod = Module.new(&block_extension)
silence_warnings do
model.parent.const_set(extension_module_name, Module.new(&block_extension))
model.parent.const_set(extension_module_name, mod)
end

prev_scope = @scope

if prev_scope
@scope = proc { |owner| instance_exec(owner, &prev_scope).extending(mod) }
else
@scope = proc { extending(mod) }
end
options[:extend].push("#{model.parent}::#{extension_module_name}".constantize)
end
end

def extension_module_name
@extension_module_name ||= "#{model.to_s.demodulize}#{name.to_s.camelize}AssociationExtension"
@extension_module_name ||= "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension"
end

def define_callback(callback_name)
Expand Down
2 changes: 1 addition & 1 deletion activerecord/lib/active_record/relation/query_methods.rb
Expand Up @@ -529,7 +529,7 @@ def extending(*modules, &block)
def extending!(*modules, &block)
modules << Module.new(&block) if block_given?

self.extending_values = modules.flatten
self.extending_values += modules.flatten
extend(*extending_values) if extending_values.any?

self
Expand Down
2 changes: 1 addition & 1 deletion activerecord/test/cases/associations/extension_test.rb
Expand Up @@ -72,6 +72,6 @@ def test_proxy_association_after_scoped
def extension_name(model)
builder = ActiveRecord::Associations::Builder::HasMany.new(model, :association_name, nil, {}) { }
builder.send(:wrap_block_extension)
builder.options[:extend].first.name
builder.extension_module.name
end
end
7 changes: 5 additions & 2 deletions activerecord/test/cases/relation_test.rb
Expand Up @@ -191,11 +191,14 @@ def relation
end

test 'extending!' do
mod = Module.new
mod, mod2 = Module.new, Module.new

assert relation.extending!(mod).equal?(relation)
assert [mod], relation.extending_values
assert_equal [mod], relation.extending_values
assert relation.is_a?(mod)

relation.extending!(mod2)
assert_equal [mod, mod2], relation.extending_values
end

test 'extending! with empty args' do
Expand Down

0 comments on commit 7fa9cb5

Please sign in to comment.