Properly proxy to Enumerable or AR::Finder method.
Decorated associations implement Enumerable, but they also should emulate the AR::Finder stuff. @person = PersonDecorator.find(params[:person_id]) @pet = @person.pets.find(params[:id]) The problem is, pets delegated to Enumerable always, instead of to the finder method. This patch makes it delegate to Enumerable if a block is given, and Finder if not. Fixes #214.
This commit is contained in:
parent
5da443366c
commit
d46d19205e
|
@ -64,6 +64,7 @@ module Draper
|
|||
orig_association = model.send(association_symbol)
|
||||
|
||||
return orig_association if orig_association.nil?
|
||||
return decorated_associations[association_symbol] if decorated_associations[association_symbol]
|
||||
|
||||
orig_association = orig_association.send(options[:scope]) if options[:scope]
|
||||
|
||||
|
@ -79,7 +80,7 @@ module Draper
|
|||
orig_association.class
|
||||
end
|
||||
|
||||
"#{klass}Decorator".constantize.decorate(orig_association, options)
|
||||
decorated_associations[association_symbol] = "#{klass}Decorator".constantize.decorate(orig_association, options)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -303,5 +304,9 @@ module Draper
|
|||
model.class.reflect_on_association(association)
|
||||
end
|
||||
end
|
||||
|
||||
def decorated_associations
|
||||
@decorated_associations ||= {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require 'active_support/core_ext/object/blank'
|
||||
module Draper
|
||||
class DecoratedEnumerableProxy
|
||||
include Enumerable
|
||||
|
@ -13,6 +14,16 @@ module Draper
|
|||
end
|
||||
alias_method :to_ary, :decorated_collection
|
||||
|
||||
def find(ifnone_or_id = nil, &blk)
|
||||
if block_given?
|
||||
source.find(ifnone_or_id, &blk)
|
||||
else
|
||||
obj = decorated_collection.first
|
||||
return nil if obj.blank?
|
||||
obj.class.find(ifnone_or_id)
|
||||
end
|
||||
end
|
||||
|
||||
def method_missing (method, *args, &block)
|
||||
@wrapped_collection.send(method, *args, &block)
|
||||
end
|
||||
|
|
|
@ -178,6 +178,23 @@ describe Draper::Base do
|
|||
subject.previous_version.should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "#find" do
|
||||
before(:each){ subject.class_eval{ decorates_association :similar_products } }
|
||||
context "with a block" do
|
||||
it "delegates to #each" do
|
||||
subject.similar_products.source.should_receive :find
|
||||
subject.similar_products.find {|p| p.title == "title" }
|
||||
end
|
||||
end
|
||||
|
||||
context "without a block" do
|
||||
it "calls a finder method" do
|
||||
subject.similar_products.source.should_not_receive :find
|
||||
subject.similar_products.find 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context('.decorates_associations') do
|
||||
|
|
Loading…
Reference in New Issue