mirror of
https://github.com/drapergem/draper
synced 2023-03-27 23:21:17 -04:00
Reworked handling of options/context and resolved double-decoration
This commit is contained in:
parent
81781988fa
commit
d154059572
2 changed files with 41 additions and 3 deletions
|
@ -2,7 +2,7 @@ module Draper
|
||||||
class Base
|
class Base
|
||||||
require 'active_support/core_ext/class/attribute'
|
require 'active_support/core_ext/class/attribute'
|
||||||
class_attribute :denied, :allowed, :model_class
|
class_attribute :denied, :allowed, :model_class
|
||||||
attr_accessor :context, :model
|
attr_accessor :model, :options
|
||||||
|
|
||||||
DEFAULT_DENIED = Object.new.methods << :method_missing
|
DEFAULT_DENIED = Object.new.methods << :method_missing
|
||||||
FORCED_PROXY = [:to_param, :id]
|
FORCED_PROXY = [:to_param, :id]
|
||||||
|
@ -23,7 +23,7 @@ module Draper
|
||||||
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 = options.fetch(:context, {})
|
self.options = options
|
||||||
end
|
end
|
||||||
|
|
||||||
# Proxies to the class specified by `decorates` to automatically
|
# Proxies to the class specified by `decorates` to automatically
|
||||||
|
@ -119,7 +119,10 @@ module Draper
|
||||||
# @param [Object] instance(s) to wrap
|
# @param [Object] instance(s) to wrap
|
||||||
# @param [Hash] options (optional)
|
# @param [Hash] options (optional)
|
||||||
def self.decorate(input, options = {})
|
def self.decorate(input, options = {})
|
||||||
if input.respond_to?(:each)
|
if input.instance_of?(self)
|
||||||
|
input.options = options unless options.empty?
|
||||||
|
return input
|
||||||
|
elsif input.respond_to?(:each)
|
||||||
Draper::DecoratedEnumerableProxy.new(input, self, options)
|
Draper::DecoratedEnumerableProxy.new(input, self, options)
|
||||||
elsif options[:infer]
|
elsif options[:infer]
|
||||||
input.decorator(options)
|
input.decorator(options)
|
||||||
|
@ -214,6 +217,14 @@ module Draper
|
||||||
super || model_class.respond_to?(method)
|
super || model_class.respond_to?(method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def context
|
||||||
|
options.fetch(:context, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
def context=(input)
|
||||||
|
options[:context] = input
|
||||||
|
end
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -224,6 +224,25 @@ describe Draper::Base do
|
||||||
let(:source) { Product.new }
|
let(:source) { Product.new }
|
||||||
|
|
||||||
it { should be_instance_of(Draper::Base) }
|
it { should be_instance_of(Draper::Base) }
|
||||||
|
|
||||||
|
context "when the input is already decorated" do
|
||||||
|
it "does not perform double-decoration" do
|
||||||
|
decorated = ProductDecorator.decorate(source)
|
||||||
|
ProductDecorator.decorate(decorated).object_id.should == decorated.object_id
|
||||||
|
end
|
||||||
|
|
||||||
|
it "overwrites options with provided options" do
|
||||||
|
first_run = ProductDecorator.decorate(source, :context => {:role => :user})
|
||||||
|
second_run = ProductDecorator.decorate(first_run, :context => {:role => :admin})
|
||||||
|
second_run.context[:role].should == :admin
|
||||||
|
end
|
||||||
|
|
||||||
|
it "leaves existing options if none are supplied" do
|
||||||
|
first_run = ProductDecorator.decorate(source, :context => {:role => :user})
|
||||||
|
second_run = ProductDecorator.decorate(first_run)
|
||||||
|
second_run.context[:role].should == :user
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -247,6 +266,14 @@ describe Draper::Base do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with options" do
|
||||||
|
let(:options) {{ :more => "settings" }}
|
||||||
|
|
||||||
|
subject { Draper::Base.decorate(source, options ) }
|
||||||
|
|
||||||
|
its(:options) { should eq(options) }
|
||||||
|
end
|
||||||
|
|
||||||
context "does not infer collections by default" do
|
context "does not infer collections by default" do
|
||||||
subject { Draper::Base.decorate(source).to_ary }
|
subject { Draper::Base.decorate(source).to_ary }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue