Permalink
Browse files

support frill'ing with only a subset of decorators

  • Loading branch information...
1 parent 2adc7d6 commit 838ba3975cfecb86be3aaf6440a66c4ced275d07 @moonmaster9000 committed Sep 9, 2012
View
@@ -2,3 +2,4 @@
*.gem
.idea
Gemfile.lock
+tags
View
@@ -8,19 +8,26 @@ def self.included base
def self.decorators
@decorators ||= dependency_graph.to_a
+ @decorators.dup
end
def self.reset!
@decorators = nil
@dependency_graph = nil
end
- def self.decorate object, context
- decorators.each do |d|
- object.extend d if d.frill? object, context
- end
+ def self.decorate object, context, options={}
+ frills = decorators
- object
+ if subset = options[:with]
+ frills.select! {|d| subset.include? d}
+ end
+
+ frills.each do |f|
+ object.extend f if f.frill? object, context
+ end
+
+ object
end
def self.dependency_graph
View
@@ -23,13 +23,42 @@ def self.auto_frill
helper_method :frill
private
- def frill object
- if object.respond_to?(:each)
- object.each do |o|
- Frill.decorate o, self
+ def frill object, options={}
+ RailsFrillHelper.new(object, self, options).frill
+ end
+
+ class RailsFrillHelper
+ def initialize(object, controller, options)
+ @object = object
+ @controller = controller
+ @options = options
+ end
+
+ def frill
+ extend_with_view_context
+ frill_object
+ object
+ end
+
+ private
+ attr_reader :options, :object, :controller
+
+ def frill_object
+ objects.each do |o|
+ Frill.decorate o, controller, options
+ end
+ end
+
+ def extend_with_view_context
+ options[:with] << ViewContextFrill if options[:with]
+ end
+
+ def objects
+ if object.respond_to? :each
+ object
+ else
+ [object]
end
- else
- Frill.decorate object, self
end
end
end
View
@@ -104,6 +104,14 @@ Or, in a view:
<%= render frill(@foo.comments) %>
```
+### 'frill' with only a subset of frills
+
+You can tell `frill` to consider only a subset of frills for decoration with the `with` option:
+
+```erb
+<%= render frill(@posts, with: [TextPostFrill, PicturePostFrill, VideoPostFrill])
+```
+
## A longer story
Your product manager writes the following story for you:
View
@@ -42,11 +42,33 @@ def self.frill? object, context
end
end
- it "should decorate the object with any applicable modules" do
- Frill.decorate object, object_context
+ context "(object, context)" do
+ it "should decorate the object with any applicable modules" do
+ Frill.decorate object, object_context
- eigenclass.included_modules.should include applicable_module
- eigenclass.included_modules.should_not include unapplicable_module
+ eigenclass.included_modules.should include applicable_module
+ eigenclass.included_modules.should_not include unapplicable_module
+ end
+ end
+
+ context "(object, context, with: module_subset)" do
+ let!(:another_applicable_module) do
+ Module.new do
+ include Frill
+
+ def self.frill?(*)
+ true
+ end
+ end
+ end
+
+ it "should only attempt to frill with the specified module subset" do
+ Frill.decorate object, object_context, with: [another_applicable_module]
+
+ eigenclass.included_modules.should include another_applicable_module
+ eigenclass.included_modules.should_not include applicable_module
+ eigenclass.included_modules.should_not include unapplicable_module
+ end
end
end
@@ -9,4 +9,9 @@ def index
def associations
@model = Model.new
end
+
+ def frill_subset
+ @model = frill Model.new, with: [BoldTitleFrill]
+ respond_with @model, template: "home/index"
+ end
end
@@ -2,6 +2,7 @@
root to: "home#index"
match "associations" => "home#associations", as: "associations"
+ match "frill_subset" => "home#frill_subset", as: "frill_subset"
match "auto_frill" => "auto_frill#index", as: "auto_frill"
end
@@ -15,4 +15,9 @@
visit auto_frill_path
page.should have_content "Decorated Title"
end
+
+ it "should let you optionally specify a subset of frills to decorate with" do
+ visit frill_subset_path
+ page.should have_content "Title http://www.example.com"
+ end
end

0 comments on commit 838ba39

Please sign in to comment.