Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Makes decorates_association work transparently with Plain Old Ruby Ob…

…jects.
  • Loading branch information...
commit f7eca344ccf58e943ef9f5835f7dabfee9f517fd 1 parent d327038
Guilherme Cirne authored
20 lib/draper/base.rb
@@ -64,15 +64,21 @@ def self.decorates(input, options = {})
64 64 def self.decorates_association(association_symbol, options = {})
65 65 define_method(association_symbol) do
66 66 orig_association = model.send(association_symbol)
67   - return orig_association if orig_association.nil?
68   - if options[:with]
69   - options[:with].decorate(orig_association)
70   - elsif options[:polymorphic]
71   - "#{orig_association.class}Decorator".constantize.decorate(orig_association)
  67 +
  68 + return orig_association if orig_association.nil?
  69 +
  70 + return options[:with].decorate(orig_association) if options[:with]
  71 +
  72 + if options[:polymorphic]
  73 + klass = orig_association.class
  74 + elsif model.class.respond_to?(:reflect_on_association) && model.class.reflect_on_association(association_symbol)
  75 + klass = model.class.reflect_on_association(association_symbol).klass
  76 + elsif orig_association.respond_to?(:first)
  77 + klass = orig_association.first.class
72 78 else
73   - reflection = model.class.reflect_on_association(association_symbol)
74   - "#{reflection.klass}Decorator".constantize.decorate(orig_association, options)
  79 + klass = orig_association.class
75 80 end
  81 + "#{klass}Decorator".constantize.decorate(orig_association, options)
76 82 end
77 83 end
78 84
29 spec/draper/base_spec.rb
@@ -113,22 +113,31 @@ class CustomDecorator < Draper::Base
113 113 end
114 114
115 115 context(".decorates_association") do
116   - context "for collection associations" do
  116 + context "for ActiveModel collection associations" do
117 117 before(:each){ subject.class_eval{ decorates_association :similar_products } }
118 118 it "causes the association's method to return a collection of wrapped objects" do
119 119 subject.similar_products.each{ |decorated| decorated.should be_instance_of(ProductDecorator) }
120 120 end
121 121 end
122 122
123   - context "for a singular association" do
  123 + context "for Plain Old Ruby Object collection associations" do
  124 + before(:each){ subject.class_eval{ decorates_association :poro_similar_products } }
  125 + it "causes the association's method to return a collection of wrapped objects" do
  126 + subject.poro_similar_products.each{ |decorated| decorated.should be_instance_of(ProductDecorator) }
  127 + end
  128 + end
  129 +
  130 + context "for an ActiveModel singular association" do
124 131 before(:each){ subject.class_eval{ decorates_association :previous_version } }
125 132 it "causes the association's method to return a single wrapped object if the association is singular" do
126 133 subject.previous_version.should be_instance_of(ProductDecorator)
127 134 end
  135 + end
128 136
129   - it "causes the association's method to return nil if the association is nil" do
130   - source.stub(:previous_version){ nil }
131   - subject.previous_version.should be_nil
  137 + context "for a Plain Old Ruby Object singular association" do
  138 + before(:each){ subject.class_eval{ decorates_association :poro_previous_version } }
  139 + it "causes the association's method to return a single wrapped object" do
  140 + subject.poro_previous_version.should be_instance_of(ProductDecorator)
132 141 end
133 142 end
134 143
@@ -145,6 +154,16 @@ class CustomDecorator < Draper::Base
145 154 subject.thing.should be_instance_of(SomeThingDecorator)
146 155 end
147 156 end
  157 +
  158 + context "when the association is nil" do
  159 + before(:each) do
  160 + subject.class_eval{ decorates_association :previous_version }
  161 + source.stub(:previous_version){ nil }
  162 + end
  163 + it "causes the association's method to return nil" do
  164 + subject.previous_version.should be_nil
  165 + end
  166 + end
148 167 end
149 168
150 169 context('.decorates_associations') do
11 spec/support/samples/product.rb
@@ -54,7 +54,7 @@ def block
54 54 end
55 55
56 56 def self.reflect_on_association(association_symbol)
57   - OpenStruct.new(:klass => self)
  57 + association_symbol.to_s.starts_with?("poro") ? nil : OpenStruct.new(:klass => self)
58 58 end
59 59
60 60 def similar_products
@@ -68,4 +68,13 @@ def previous_version
68 68 def thing
69 69 SomeThing.new
70 70 end
  71 +
  72 + def poro_similar_products
  73 + [Product.new, Product.new]
  74 + end
  75 +
  76 + def poro_previous_version
  77 + Product.new
  78 + end
  79 +
71 80 end

0 comments on commit f7eca34

Please sign in to comment.
Something went wrong with that request. Please try again.