Generalize to pass an options hash to decorators
This commit is contained in:
parent
78b200a84f
commit
03910877d0
|
@ -15,15 +15,15 @@ module Draper
|
||||||
|
|
||||||
# Initialize a new decorator instance by passing in
|
# Initialize a new decorator instance by passing in
|
||||||
# an instance of the source class. Pass in an optional
|
# an instance of the source class. Pass in an optional
|
||||||
# context is stored for later use.
|
# context inside the options hash is stored for later use.
|
||||||
#
|
#
|
||||||
# @param [Object] instance to wrap
|
# @param [Object] instance to wrap
|
||||||
# @param [Object] context (optional)
|
# @param [Hash] options (optional)
|
||||||
def initialize(input, context = {})
|
def initialize(input, options = {})
|
||||||
input.inspect # forces evaluation of a lazy query from AR
|
input.inspect # forces evaluation of a lazy query from AR
|
||||||
self.class.model_class = input.class if model_class.nil?
|
self.class.model_class = input.class if model_class.nil?
|
||||||
@model = input
|
@model = input
|
||||||
self.context = context
|
self.context = options.fetch(:context, {})
|
||||||
end
|
end
|
||||||
|
|
||||||
# Proxies to the class specified by `decorates` to automatically
|
# Proxies to the class specified by `decorates` to automatically
|
||||||
|
@ -31,8 +31,8 @@ module Draper
|
||||||
#
|
#
|
||||||
# @param [Symbol or String] id to lookup
|
# @param [Symbol or String] id to lookup
|
||||||
# @return [Object] instance of this decorator class
|
# @return [Object] instance of this decorator class
|
||||||
def self.find(input, context = {})
|
def self.find(input, options = {})
|
||||||
self.new(model_class.find(input), context)
|
self.new(model_class.find(input), options)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Typically called within a decorator definition, this method
|
# Typically called within a decorator definition, this method
|
||||||
|
@ -43,7 +43,7 @@ module Draper
|
||||||
# But they don't have to match in name, so a `EmployeeDecorator`
|
# But they don't have to match in name, so a `EmployeeDecorator`
|
||||||
# class could call `decorates :person` to wrap instances of `Person`
|
# class could call `decorates :person` to wrap instances of `Person`
|
||||||
#
|
#
|
||||||
# This is primarilly set so the `.find` method knows which class
|
# This is primarilly set so the `.find` method knows which class
|
||||||
# to query.
|
# to query.
|
||||||
#
|
#
|
||||||
# @param [Symbol] class_name snakecase name of the decorated class, like `:product`
|
# @param [Symbol] class_name snakecase name of the decorated class, like `:product`
|
||||||
|
@ -83,7 +83,7 @@ module Draper
|
||||||
|
|
||||||
# Initialize a new decorator instance by passing in
|
# Initialize a new decorator instance by passing in
|
||||||
# an instance of the source class. Pass in an optional
|
# an instance of the source class. Pass in an optional
|
||||||
# context is stored for later use.
|
# context into the options hash is stored for later use.
|
||||||
#
|
#
|
||||||
# When passing in a single object, using `.decorate` is
|
# When passing in a single object, using `.decorate` is
|
||||||
# identical to calling `.new`. However, `.decorate` can
|
# identical to calling `.new`. However, `.decorate` can
|
||||||
|
@ -91,31 +91,31 @@ module Draper
|
||||||
# individually decorated objects.
|
# individually decorated objects.
|
||||||
#
|
#
|
||||||
# @param [Object] instance(s) to wrap
|
# @param [Object] instance(s) to wrap
|
||||||
# @param [Object] context (optional)
|
# @param [Hash] options (optional)
|
||||||
def self.decorate(input, context = {})
|
def self.decorate(input, options = {})
|
||||||
input.respond_to?(:each) ? Draper::DecoratedEnumerableProxy.new(input, self, context) : new(input, context)
|
input.respond_to?(:each) ? Draper::DecoratedEnumerableProxy.new(input, self, options) : new(input, options)
|
||||||
end
|
|
||||||
|
|
||||||
# Fetch all instances of the decorated class and decorate them.
|
|
||||||
#
|
|
||||||
# @param [Object] context (optional)
|
|
||||||
# @return [Draper::DecoratedEnumerableProxy]
|
|
||||||
def self.all(context = {})
|
|
||||||
Draper::DecoratedEnumerableProxy.new(model_class.all, self, context)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.first(context = {})
|
|
||||||
decorate(model_class.first, context)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.last(context = {})
|
# Fetch all instances of the decorated class and decorate them.
|
||||||
decorate(model_class.last, context)
|
#
|
||||||
|
# @param [Hash] options (optional)
|
||||||
|
# @return [Draper::DecoratedEnumerableProxy]
|
||||||
|
def self.all(options = {})
|
||||||
|
Draper::DecoratedEnumerableProxy.new(model_class.all, self, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.first(options = {})
|
||||||
|
decorate(model_class.first, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.last(options = {})
|
||||||
|
decorate(model_class.last, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Access the helpers proxy to call built-in and user-defined
|
# Access the helpers proxy to call built-in and user-defined
|
||||||
# Rails helpers. Aliased to `.h` for convinience.
|
# Rails helpers. Aliased to `.h` for convinience.
|
||||||
#
|
#
|
||||||
# @return [Object] proxy
|
# @return [Object] proxy
|
||||||
def helpers
|
def helpers
|
||||||
self.class.helpers
|
self.class.helpers
|
||||||
end
|
end
|
||||||
|
@ -124,13 +124,13 @@ module Draper
|
||||||
# Access the helpers proxy to call built-in and user-defined
|
# Access the helpers proxy to call built-in and user-defined
|
||||||
# Rails helpers from a class context.
|
# Rails helpers from a class context.
|
||||||
#
|
#
|
||||||
# @return [Object] proxy
|
# @return [Object] proxy
|
||||||
class << self
|
class << self
|
||||||
def helpers
|
def helpers
|
||||||
Draper::ViewContext.current
|
Draper::ViewContext.current
|
||||||
end
|
end
|
||||||
alias :h :helpers
|
alias :h :helpers
|
||||||
end
|
end
|
||||||
|
|
||||||
# Fetch the original wrapped model.
|
# Fetch the original wrapped model.
|
||||||
#
|
#
|
||||||
|
@ -141,7 +141,7 @@ module Draper
|
||||||
|
|
||||||
# Delegates == to the decorated models
|
# Delegates == to the decorated models
|
||||||
#
|
#
|
||||||
# @return [Boolean] true if other's model == self's model
|
# @return [Boolean] true if other's model == self's model
|
||||||
def ==(other)
|
def ==(other)
|
||||||
@model == (other.respond_to?(:model) ? other.model : other)
|
@model == (other.respond_to?(:model) ? other.model : other)
|
||||||
end
|
end
|
||||||
|
@ -165,11 +165,11 @@ module Draper
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.method_missing(method, *args, &block)
|
def self.method_missing(method, *args, &block)
|
||||||
model_class.send(method, *args, &block)
|
model_class.send(method, *args, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.respond_to?(method, include_private = false)
|
def self.respond_to?(method, include_private = false)
|
||||||
super || model_class.respond_to?(method)
|
super || model_class.respond_to?(method)
|
||||||
end
|
end
|
||||||
|
@ -177,6 +177,6 @@ module Draper
|
||||||
private
|
private
|
||||||
def allow?(method)
|
def allow?(method)
|
||||||
(!allowed? || allowed.include?(method) || FORCED_PROXY.include?(method)) && !denied.include?(method)
|
(!allowed? || allowed.include?(method) || FORCED_PROXY.include?(method)) && !denied.include?(method)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,16 +2,16 @@ module Draper
|
||||||
class DecoratedEnumerableProxy
|
class DecoratedEnumerableProxy
|
||||||
include Enumerable
|
include Enumerable
|
||||||
|
|
||||||
def initialize(collection, klass, context)
|
def initialize(collection, klass, options = {})
|
||||||
@wrapped_collection, @klass, @context = collection, klass, context
|
@wrapped_collection, @klass, @options = collection, klass, options
|
||||||
end
|
end
|
||||||
|
|
||||||
def each(&block)
|
def each(&block)
|
||||||
@wrapped_collection.each { |member| block.call(@klass.new(member, @context)) }
|
@wrapped_collection.each { |member| block.call(@klass.new(member, @options)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_ary
|
def to_ary
|
||||||
@wrapped_collection.map { |member| @klass.new(member, @context) }
|
@wrapped_collection.map { |member| @klass.new(member, @options) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def method_missing (method, *args, &block)
|
def method_missing (method, *args, &block)
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
module Draper::ModelSupport
|
module Draper::ModelSupport
|
||||||
def decorator
|
def decorator(options = {})
|
||||||
@decorator ||= "#{self.class.name}Decorator".constantize.decorate(self)
|
@decorator ||= "#{self.class.name}Decorator".constantize.decorate(self, options)
|
||||||
block_given? ? yield(@decorator) : @decorator
|
block_given? ? yield(@decorator) : @decorator
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :decorate :decorator
|
alias :decorate :decorator
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def decorate(context = {})
|
def decorate(options = {})
|
||||||
@decorator_proxy ||= "#{model_name}Decorator".constantize.decorate(self.scoped)
|
@decorator_proxy ||= "#{model_name}Decorator".constantize.decorate(self.scoped, options)
|
||||||
block_given? ? yield(@decorator_proxy) : @decorator_proxy
|
block_given? ? yield(@decorator_proxy) : @decorator_proxy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -135,7 +135,7 @@ describe Draper::Base do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should accept and store a context" do
|
it "should accept and store a context" do
|
||||||
pd = ProductDecorator.find(1, :admin)
|
pd = ProductDecorator.find(1, :context => :admin)
|
||||||
pd.context.should == :admin
|
pd.context.should == :admin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -164,7 +164,7 @@ describe Draper::Base do
|
||||||
context "with a context" do
|
context "with a context" do
|
||||||
let(:context) {{ :some => 'data' }}
|
let(:context) {{ :some => 'data' }}
|
||||||
|
|
||||||
subject { Draper::Base.decorate(source, context) }
|
subject { Draper::Base.decorate(source, :context => context) }
|
||||||
|
|
||||||
context "when given a collection of source objects" do
|
context "when given a collection of source objects" do
|
||||||
let(:source) { [Product.new, Product.new] }
|
let(:source) { [Product.new, Product.new] }
|
||||||
|
@ -189,7 +189,7 @@ describe Draper::Base do
|
||||||
subject.should == other
|
subject.should == other
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'position accessors' do
|
context 'position accessors' do
|
||||||
[:first, :last].each do |method|
|
[:first, :last].each do |method|
|
||||||
context "##{method}" do
|
context "##{method}" do
|
||||||
|
@ -202,9 +202,9 @@ describe Draper::Base do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should accept an optional context" do
|
it "should accept an optional context" do
|
||||||
ProductDecorator.send(method, :admin).context.should == :admin
|
ProductDecorator.send(method, :context => :admin).context.should == :admin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -273,9 +273,9 @@ describe Draper::Base do
|
||||||
it "should return a decorated collection" do
|
it "should return a decorated collection" do
|
||||||
ProductDecorator.all.first.should be_instance_of ProductDecorator
|
ProductDecorator.all.first.should be_instance_of ProductDecorator
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should accept a context" do
|
it "should accept a context" do
|
||||||
collection = ProductDecorator.all(:admin)
|
collection = ProductDecorator.all(:context => :admin)
|
||||||
collection.first.context.should == :admin
|
collection.first.context.should == :admin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue