Provide support for class methods. Reintroduce the decorates class method, which may be used to hint at which class to delegate class methods to.
This commit is contained in:
parent
41ca1a3203
commit
731995a5fe
|
@ -45,7 +45,33 @@ module Draper
|
||||||
# @option options [Class, Symbol] :for The model class to find
|
# @option options [Class, Symbol] :for The model class to find
|
||||||
def self.has_finders(options = {})
|
def self.has_finders(options = {})
|
||||||
extend Draper::Finders
|
extend Draper::Finders
|
||||||
self.finder_class = options[:for] || name.chomp("Decorator")
|
if klass = options.delete(:for)
|
||||||
|
decorates klass
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
# Specify the class that this class decorates.
|
||||||
|
#
|
||||||
|
# @param [String, Symbol, Class] Class or name of class to decorate.
|
||||||
|
def decorates(klass)
|
||||||
|
@source_class = klass.kind_of?(Class) ? klass : klass.to_s.classify.constantize
|
||||||
|
end
|
||||||
|
|
||||||
|
# Provides access to the class that this decorator decorates
|
||||||
|
#
|
||||||
|
# @return [Class]: The class wrapped by the decorator
|
||||||
|
def source_class
|
||||||
|
@source_class ||= name.chomp("Decorator").constantize
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_missing(method, *args, &block)
|
||||||
|
source_class.send(method, *args, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def respond_to?(method, include_private = false)
|
||||||
|
super || source_class.respond_to?(method)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Typically called within a decorator definition, this method causes
|
# Typically called within a decorator definition, this method causes
|
||||||
|
|
|
@ -1,29 +1,24 @@
|
||||||
module Draper
|
module Draper
|
||||||
module Finders
|
module Finders
|
||||||
|
|
||||||
attr_reader :finder_class
|
|
||||||
def finder_class=(klass)
|
|
||||||
@finder_class = klass.to_s.camelize.constantize
|
|
||||||
end
|
|
||||||
|
|
||||||
def find(id, options = {})
|
def find(id, options = {})
|
||||||
decorate(finder_class.find(id), options)
|
decorate(source_class.find(id), options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def all(options = {})
|
def all(options = {})
|
||||||
decorate_collection(finder_class.all, options)
|
decorate_collection(source_class.all, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def first(options = {})
|
def first(options = {})
|
||||||
decorate(finder_class.first, options)
|
decorate(source_class.first, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def last(options = {})
|
def last(options = {})
|
||||||
decorate(finder_class.last, options)
|
decorate(source_class.last, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def method_missing(method, *args, &block)
|
def method_missing(method, *args, &block)
|
||||||
result = finder_class.send(method, *args, &block)
|
result = source_class.send(method, *args, &block)
|
||||||
options = args.extract_options!
|
options = args.extract_options!
|
||||||
|
|
||||||
case method.to_s
|
case method.to_s
|
||||||
|
@ -35,10 +30,5 @@ module Draper
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def respond_to?(method, include_private = false)
|
|
||||||
super || finder_class.respond_to?(method)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -450,12 +450,12 @@ describe Draper::Decorator do
|
||||||
|
|
||||||
context "with no options" do
|
context "with no options" do
|
||||||
it "infers the finder class" do
|
it "infers the finder class" do
|
||||||
ProductDecorator.finder_class.should be Product
|
ProductDecorator.source_class.should be Product
|
||||||
end
|
end
|
||||||
|
|
||||||
context "for a namespaced model" do
|
context "for a namespaced model" do
|
||||||
it "infers the finder class" do
|
it "infers the finder class" do
|
||||||
Namespace::ProductDecorator.finder_class.should be Namespace::Product
|
Namespace::ProductDecorator.source_class.should be Namespace::Product
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -466,21 +466,21 @@ describe Draper::Decorator do
|
||||||
context "with a symbol" do
|
context "with a symbol" do
|
||||||
it "sets the finder class" do
|
it "sets the finder class" do
|
||||||
subject.has_finders for: :product
|
subject.has_finders for: :product
|
||||||
subject.finder_class.should be Product
|
subject.source_class.should be Product
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with a string" do
|
context "with a string" do
|
||||||
it "sets the finder class" do
|
it "sets the finder class" do
|
||||||
subject.has_finders for: "some_thing"
|
subject.has_finders for: "some_thing"
|
||||||
subject.finder_class.should be SomeThing
|
subject.source_class.should be SomeThing
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with a class" do
|
context "with a class" do
|
||||||
it "sets the finder_class" do
|
it "sets the source_class" do
|
||||||
subject.has_finders for: Namespace::Product
|
subject.has_finders for: Namespace::Product
|
||||||
subject.finder_class.should be Namespace::Product
|
subject.source_class.should be Namespace::Product
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -494,4 +494,18 @@ describe Draper::Decorator do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "class methods" do
|
||||||
|
it "passes through to the underlying wrapped class" do
|
||||||
|
ProductDecorator.sample_class_method.should == Product.sample_class_method
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when told to decorate a different class " do
|
||||||
|
subject { decorator_class }
|
||||||
|
before { decorator_class.decorates :product }
|
||||||
|
|
||||||
|
it "should manually set the class to pass methods to" do
|
||||||
|
subject.sample_class_method.should == Product.sample_class_method
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,4 +22,8 @@ class PostDecorator < Draper::Decorator
|
||||||
def url_with_id
|
def url_with_id
|
||||||
h.post_url(id: id)
|
h.post_url(id: id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def link
|
||||||
|
h.link_to id.to_s, self
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,4 +20,7 @@ describe PostDecorator do
|
||||||
subject.url_with_id.should == "http://www.example.com/en/posts/#{source.id}"
|
subject.url_with_id.should == "http://www.example.com/en/posts/#{source.id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "can be passed implicitly to url_for" do
|
||||||
|
subject.link.should == "<a href=\"/en/posts/#{source.id}\">#{source.id}</a>"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue