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)
|
orig_association = model.send(association_symbol)
|
||||||
|
|
||||||
return orig_association if orig_association.nil?
|
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]
|
orig_association = orig_association.send(options[:scope]) if options[:scope]
|
||||||
|
|
||||||
|
@ -79,7 +80,7 @@ module Draper
|
||||||
orig_association.class
|
orig_association.class
|
||||||
end
|
end
|
||||||
|
|
||||||
"#{klass}Decorator".constantize.decorate(orig_association, options)
|
decorated_associations[association_symbol] = "#{klass}Decorator".constantize.decorate(orig_association, options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -303,5 +304,9 @@ module Draper
|
||||||
model.class.reflect_on_association(association)
|
model.class.reflect_on_association(association)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def decorated_associations
|
||||||
|
@decorated_associations ||= {}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
require 'active_support/core_ext/object/blank'
|
||||||
module Draper
|
module Draper
|
||||||
class DecoratedEnumerableProxy
|
class DecoratedEnumerableProxy
|
||||||
include Enumerable
|
include Enumerable
|
||||||
|
@ -13,6 +14,16 @@ module Draper
|
||||||
end
|
end
|
||||||
alias_method :to_ary, :decorated_collection
|
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)
|
def method_missing (method, *args, &block)
|
||||||
@wrapped_collection.send(method, *args, &block)
|
@wrapped_collection.send(method, *args, &block)
|
||||||
end
|
end
|
||||||
|
|
|
@ -178,6 +178,23 @@ describe Draper::Base do
|
||||||
subject.previous_version.should be_nil
|
subject.previous_version.should be_nil
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
context('.decorates_associations') do
|
context('.decorates_associations') do
|
||||||
|
|
Loading…
Reference in New Issue