Skip to content
Newer
Older
100644 388 lines (269 sloc) 13.5 KB
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 26, 2011
1 # Draper: View Models for Rails
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
2
c222dbe @laserlemon Link build status and add dependency status to README
laserlemon authored Jan 7, 2012
3 [![TravisCI Build Status](https://secure.travis-ci.org/jcasimir/draper.png)](http://travis-ci.org/jcasimir/draper)
6abf506 @jcasimir Adding status image for TravisCI
jcasimir authored Oct 8, 2011
4
d4b1b91 @jcasimir Writing README instead of sleeping
jcasimir authored Jul 26, 2011
5 ## Quick Start
6
7 1. Add `gem 'draper'` to your `Gemfile` and `bundle`
5549614 @steveklabnik fixing generator names in README
steveklabnik authored May 9, 2012
8 2. When you generate a resource with `rails g resource YourModel`, you get a decorator automatically!
9243523 @jcasimir Update Readme.markdown
jcasimir authored Oct 5, 2012
9 3. If `YourModel` already exists, run `rails g decorator YourModel` to create `YourModelDecorator`
5549614 @steveklabnik fixing generator names in README
steveklabnik authored May 9, 2012
10 4. Edit `app/decorators/[your_model]_decorator.rb` using:
d4b1b91 @jcasimir Writing README instead of sleeping
jcasimir authored Jul 27, 2011
11 1. `h` to proxy to Rails/application helpers like `h.current_user`
9243523 @jcasimir Update Readme.markdown
jcasimir authored Oct 5, 2012
12 2. the name of your decorated model to access the wrapped object like `article.created_at`
5549614 @steveklabnik fixing generator names in README
steveklabnik authored May 9, 2012
13 5. Wrap models in your controller with the decorator using:
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 29, 2011
14 1. `.find` automatic lookup & wrap
15 ex: `ArticleDecorator.find(1)`
9243523 @jcasimir Update Readme.markdown
jcasimir authored Oct 5, 2012
16 2. `.decorate` method with a single object or collection,
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 30, 2011
17 ex: `ArticleDecorator.decorate(Article.all)`
18 3. `.new` method with single object
19 ex: `ArticleDecorator.new(Article.first)`
9243523 @jcasimir Update Readme.markdown
jcasimir authored Oct 5, 2012
20 6. Call decorator methods from your view templates
21 ex: `<%= @article_decorator.created_at %>`
d4b1b91 @jcasimir Writing README instead of sleeping
jcasimir authored Jul 27, 2011
22
9155e58 @steveklabnik Generators redux.
steveklabnik authored May 9, 2012
23 If you need common methods in your decorators, create an `app/decorators/application_decorator.rb`:
24
25 ``` ruby
26 class ApplicationDecorator < Draper::Base
27 # your methods go here
28 end
29 ```
30
31 and make your decorators inherit from it. Newly generated decorators will respect this choice and inherit from `ApplicationDecorator`.
32
d4b1b91 @jcasimir Writing README instead of sleeping
jcasimir authored Jul 27, 2011
33 ## Goals
34
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 30, 2011
35 This gem makes it easy to apply the decorator pattern to domain models in a Rails application. This pattern gives you three wins:
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
36
b4f632b @jcasimir Adding in focus on view-layer data filtering based on current_user
jcasimir authored Jun 30, 2011
37 1. Replace most helpers with an object-oriented approach
38 2. Filter data at the presentation level
39 3. Enforce an interface between your controllers and view templates.
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
40
92d2146 @jcasimir Added link to tutorial / sample project
jcasimir authored Jul 12, 2011
41 ### 1. Object Oriented Helpers
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
42
203910c @jcasimir Travis trigger :)
jcasimir authored Sep 20, 2011
43 Why hate normal helpers? In Ruby/Rails we approach everything from an Object-Oriented perspective, then with helpers we get procedural.The job of a helper is to take in data and output a presentation-ready string. We can do that with a decorator.
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
44
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 26, 2011
45 A decorator wraps an object with presentation-related accessor methods. For instance, if you had an `Article` object, then the decorator could override `.published_at` to use formatted output like this:
b4f632b @jcasimir Adding in focus on view-layer data filtering based on current_user
jcasimir authored Jul 1, 2011
46
47 ```ruby
f3c8b53 @patriciomacadden changed a generator call (`rails generate decorator` instead of `rail…
patriciomacadden authored May 24, 2012
48 class ArticleDecorator < Draper::Base
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
49 decorates :article
f3c8b53 @patriciomacadden changed a generator call (`rails generate decorator` instead of `rail…
patriciomacadden authored May 24, 2012
50
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
51 def published_at
b050cd3 @jcasimir Revising README for 0.9.1 with named accessors
jcasimir authored Oct 19, 2011
52 date = h.content_tag(:span, article.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
53 time = h.content_tag(:span, article.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
54 h.content_tag :span, date + time, :class => 'created_at'
b4f632b @jcasimir Adding in focus on view-layer data filtering based on current_user
jcasimir authored Jul 1, 2011
55 end
56 end
57 ```
58
92d2146 @jcasimir Added link to tutorial / sample project
jcasimir authored Jul 12, 2011
59 ### 2. View-Layer Data Filtering
b4f632b @jcasimir Adding in focus on view-layer data filtering based on current_user
jcasimir authored Jul 1, 2011
60
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
61 Have you ever written a `to_xml` or `to_json` method in your model? Did it feel weird to put presentation logic in your model?
b4f632b @jcasimir Adding in focus on view-layer data filtering based on current_user
jcasimir authored Jul 1, 2011
62
63 Or, in the course of formatting this data, did you wish you could access `current_user` down in the model? Maybe for guests your `to_json` is only going to show three attributes, but if the user is an admin they get to see them all.
64
65 How would you handle this in the model layer? You'd probably pass the `current_user` or some role/flag down to `to_json`. That should still feel slimy.
66
6e88870 @jcasimir Minor clarity edits
jcasimir authored Aug 27, 2011
67 When you use a decorator you have the power of a Ruby object but it's a part of the view layer. This is where your `to_json` belongs. You can access your `current_user` helper method using the `h` proxy available in the decorator:
b4f632b @jcasimir Adding in focus on view-layer data filtering based on current_user
jcasimir authored Jul 1, 2011
68
69 ```ruby
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 30, 2011
70 class ArticleDecorator < ApplicationDecorator
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
71 decorates :article
f3c8b53 @patriciomacadden changed a generator call (`rails generate decorator` instead of `rail…
patriciomacadden authored May 24, 2012
72
b4f632b @jcasimir Adding in focus on view-layer data filtering based on current_user
jcasimir authored Jul 1, 2011
73 ADMIN_VISIBLE_ATTRIBUTES = [:title, :body, :author, :status]
74 PUBLIC_VISIBLE_ATTRIBUTES = [:title, :body]
75
6e88870 @jcasimir Minor clarity edits
jcasimir authored Aug 28, 2011
76 def to_json
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
77 attr_set = h.current_user.admin? ? ADMIN_VISIBLE_ATTRIBUTES : PUBLIC_VISIBLE_ATTRIBUTES
b050cd3 @jcasimir Revising README for 0.9.1 with named accessors
jcasimir authored Oct 20, 2011
78 article.to_json(:only => attr_set)
b4f632b @jcasimir Adding in focus on view-layer data filtering based on current_user
jcasimir authored Jul 1, 2011
79 end
80 end
81 ```
82
92d2146 @jcasimir Added link to tutorial / sample project
jcasimir authored Jul 12, 2011
83 ### 3. Enforcing an Interface
84
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
85 Want to strictly control what methods are proxied to the original object? Use `denies` or `allows`.
86
87 #### Using `denies`
92d2146 @jcasimir Added link to tutorial / sample project
jcasimir authored Jul 12, 2011
88
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
89 The `denies` method takes a blacklist approach. For instance:
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
90
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
91 ```ruby
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 30, 2011
92 class ArticleDecorator < ApplicationDecorator
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
93 decorates :article
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
94 denies :title
95 end
96 ```
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
97
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
98 Then, to test it:
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
99
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
100 ```irb
6e88870 @jcasimir Minor clarity edits
jcasimir authored Aug 28, 2011
101 > ad = ArticleDecorator.find(1)
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
102 => #<ArticleDecorator:0x000001020d7728 @model=#<Article id: 1, title: "Hello, World">>
6e88870 @jcasimir Minor clarity edits
jcasimir authored Aug 28, 2011
103 > ad.title
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
104 NoMethodError: undefined method `title' for #<ArticleDecorator:0x000001020d7728>
105 ```
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
106
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
107 #### Using `allows`
108
109 A better approach is to define a whitelist using `allows`:
110
111 ```ruby
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 30, 2011
112 class ArticleDecorator < ApplicationDecorator
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
113 decorates :article
114 allows :title, :description
115 end
116 ```
117
118 ```irb
198b4fe @manuelmeurer Fixed formatting in Readme
manuelmeurer authored Sep 2, 2011
119 > ad = ArticleDecorator.find(1)
120 => #<ArticleDecorator:0x000001020d7728 @model=#<Article id: 1, title: "Hello, World">>
121 > ad.title
122 => "Hello, World"
123 > ad.created_at
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
124 NoMethodError: undefined method `created_at' for #<ArticleDecorator:0x000001020d7728>
125 ```
126
f02af58 @jcasimir More Readme errors.
jcasimir authored Jul 27, 2011
127 ## Up and Running
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
128
129 ### Setup
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
130
131 Add the dependency to your `Gemfile`:
132
133 ```
134 gem "draper"
135 ```
136
5448aba @jcasimir Minor clarity revisions
jcasimir authored Oct 19, 2011
137 Then run `bundle` from the project directory.
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
138
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
139 ### Generate the Decorator
140
141 To decorate a model named `Article`:
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
142
143 ```
f1bd79b @steveklabnik Updating README.
steveklabnik authored May 11, 2012
144 rails generate decorator article
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
145 ```
146
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
147 ### Writing Methods
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
148
5448aba @jcasimir Minor clarity revisions
jcasimir authored Oct 20, 2011
149 Open the decorator model (ex: `app/decorators/article_decorator.rb`) and add normal instance methods. To access the wrapped source object, use a method named after the `decorates` argument:
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
150
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
151 ```ruby
f1bd79b @steveklabnik Updating README.
steveklabnik authored May 11, 2012
152 class ArticleDecorator < Draper::Base
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
153 decorates :article
154
155 def author_name
b050cd3 @jcasimir Revising README for 0.9.1 with named accessors
jcasimir authored Oct 20, 2011
156 article.author.first_name + " " + article.author.last_name
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
157 end
158 end
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
159 ```
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
160
161 ### Using Existing Helpers
162
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
163 You probably want to make use of Rails helpers and those defined in your application. Use the `helpers` or `h` method proxy:
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
164
165 ```ruby
f1bd79b @steveklabnik Updating README.
steveklabnik authored May 11, 2012
166 class ArticleDecorator < Draper::Base
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
167 decorates :article
168
169 def published_at
b050cd3 @jcasimir Revising README for 0.9.1 with named accessors
jcasimir authored Oct 20, 2011
170 date = h.content_tag(:span, article.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
171 time = h.content_tag(:span, article.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
172 h.content_tag :span, date + time, :class => 'created_at'
173 end
174 end
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
175 ```
176
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 30, 2011
177 #### Lazy Helpers
178
179 Hate seeing that `h.` proxy all over? Willing to mix a bazillion methods into your decorator? Then try lazy helpers:
180
181 ```ruby
f1bd79b @steveklabnik Updating README.
steveklabnik authored May 11, 2012
182 class ArticleDecorator < Draper::Base
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 30, 2011
183 decorates :article
2d3c083 @mikezter Encourage use of include keyword
mikezter authored Oct 8, 2011
184 include Draper::LazyHelpers
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 30, 2011
185
186 def published_at
b050cd3 @jcasimir Revising README for 0.9.1 with named accessors
jcasimir authored Oct 20, 2011
187 date = content_tag(:span, article.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
188 time = content_tag(:span, article.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
6d6ff66 @jcasimir This README takes more time than the implementation
jcasimir authored Jul 30, 2011
189 content_tag :span, date + time, :class => 'created_at'
190 end
191 end
192 ```
193
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
194 ### In the Controller
195
196 When writing your controller actions, you have three options:
197
198 * Call `.new` and pass in the object to be wrapped
199
198b4fe @manuelmeurer Fixed formatting in Readme
manuelmeurer authored Sep 2, 2011
200 ```ruby
d834b2d @i0rek Remove backtic.
i0rek authored Jan 10, 2012
201 ArticleDecorator.new(Article.find(params[:id]))
198b4fe @manuelmeurer Fixed formatting in Readme
manuelmeurer authored Sep 2, 2011
202 ```
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
203
204 * Call `.decorate` and pass in an object or collection of objects to be wrapped:
198b4fe @manuelmeurer Fixed formatting in Readme
manuelmeurer authored Sep 2, 2011
205
206 ```ruby
207 ArticleDecorator.decorate(Article.first) # Returns one instance of ArticleDecorator
5448aba @jcasimir Minor clarity revisions
jcasimir authored Oct 20, 2011
208 ArticleDecorator.decorate(Article.all) # Returns an enumeration proxy of ArticleDecorator instances
198b4fe @manuelmeurer Fixed formatting in Readme
manuelmeurer authored Sep 2, 2011
209 ```
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
210
d39a47f @dnagir minor spelling fix
dnagir authored Jan 3, 2012
211 * Call `.find` to automatically do a lookup on the `decorates` class:
198b4fe @manuelmeurer Fixed formatting in Readme
manuelmeurer authored Sep 2, 2011
212
213 ```ruby
214 ArticleDecorator.find(1)
215 ```
75a8204 @rf- Remove unnecessary view_context setup
rf- authored Jul 18, 2012
216
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
217 ### In Your Views
218
219 Use the new methods in your views like any other model method (ex: `@article.published_at`):
220
221 ```erb
222 <h1><%= @article.title %> <%= @article.published_at %></h1>
223 ```
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
224
358e939 @ubermajestix Moved RSpec notes under "Up and Running".
ubermajestix authored Dec 7, 2011
225 ### Integration with RSpec
226
227 Using the provided generator, Draper will place specs for your new decorator in `spec/decorators/`.
75ab9bb @ubermajestix Added notes about decorator specs that might live outside spec/decora…
ubermajestix authored Dec 7, 2011
228
1d6491b @steveklabnik kill set_current_view_context
steveklabnik authored Jul 17, 2012
229 By default, specs in `spec/decorators` will be tagged as `type => :decorator`. Any spec tagged as `decorator` will make helpers available to the decorator.
75ab9bb @ubermajestix Added notes about decorator specs that might live outside spec/decora…
ubermajestix authored Dec 7, 2011
230
231 If your decorator specs live somewhere else, which they shouldn't, make sure to tag them with `type => :decorator`. If you don't tag them, Draper's helpers won't be available to your decorator while testing.
358e939 @ubermajestix Moved RSpec notes under "Up and Running".
ubermajestix authored Dec 7, 2011
232
96a9ba0 @beerlington Update note about Spork usage
beerlington authored Jul 30, 2012
233 Note: If you're using Spork, you need to `require 'draper/test/rspec_integration'` in your Spork.prefork block.
c56ac5e @bdotdub Include Draper::ViewContextFilter in ActionMailer::Base
bdotdub authored Oct 28, 2011
234
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
235 ## Possible Decoration Methods
236
237 Here are some ideas of what you might do in decorator methods:
238
239 * Implement output formatting for `to_csv`, `to_json`, or `to_xml`
240 * Format dates and times using `strftime`
241 * Implement a commonly used representation of the data object like a `.name` method that combines `first_name` and `last_name` attributes
242
9243523 @jcasimir Update Readme.markdown
jcasimir authored Oct 5, 2012
243 ## Learning Resources
244
245 ### RailsCast
246
247 Ryan Bates has put together an excellent RailsCast on Draper based on the 0.8.0 release: http://railscasts.com/episodes/286-draper
248
249 ### Example Using a Decorator
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
250
c67edf6 @jcasimir Fixing tutorial link
jcasimir authored Feb 2, 2012
251 For a brief tutorial with sample project, check this out: http://tutorials.jumpstartlab.com/topics/decorators.html
92d2146 @jcasimir Added link to tutorial / sample project
jcasimir authored Jul 12, 2011
252
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
253 Say I have a publishing system with `Article` resources. My designer decides that whenever we print the `published_at` timestamp, it should be constructed like this:
254
255 ```html
256 <span class='published_at'>
257 <span class='date'>Monday, May 6</span>
258 <span class='time'>8:52AM</span>
259 </span>
260 ```
261
262 Could we build that using a partial? Yes. A helper? Uh-huh. But the point of the decorator is to encapsulate logic just like we would a method in our models. Here's how to implement it.
263
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
264 First, follow the steps above to add the dependency and update your bundle.
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
265
266 Since we're talking about the `Article` model we'll create an `ArticleDecorator` class. You could do it by hand, but use the provided generator:
267
268 ```
f3c8b53 @patriciomacadden changed a generator call (`rails generate decorator` instead of `rail…
patriciomacadden authored May 24, 2012
269 rails generate decorator Article
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
270 ```
271
272 Now open up the created `app/decorators/article_decorator.rb` and you'll find an `ArticleDecorator` class. Add this method:
273
274 ```ruby
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
275 def published_at
b050cd3 @jcasimir Revising README for 0.9.1 with named accessors
jcasimir authored Oct 20, 2011
276 date = h.content_tag(:span, article.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
277 time = h.content_tag(:span, article.published_at.strftime("%l:%M%p").delete(" "), :class => 'time')
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
278 h.content_tag :span, date + time, :class => 'published_at'
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
279 end
280 ```
281
282 Then you need to perform the wrapping in your controller. Here's the simplest method:
283
284 ```ruby
626462d @kuraga Error in Readme
kuraga authored Aug 30, 2012
285 class ArticlesController < ApplicationController
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
286 def show
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
287 @article = ArticleDecorator.find params[:id]
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
288 end
289 end
290 ```
291
292 Then within your views you can utilize both the normal data methods and your new presentation methods:
293
294 ```ruby
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
295 <%= @article.published_at %>
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
296 ```
297
298 Ta-da! Object-oriented data formatting for your view layer. Below is the complete decorator with extra comments removed:
299
300 ```ruby
f1bd79b @steveklabnik Updating README.
steveklabnik authored May 11, 2012
301 class ArticleDecorator < Draper::Base
5c948c6 @jcasimir Rough update to Readme
jcasimir authored Jul 27, 2011
302 decorates :article
303
49fd635 @jcasimir Ton of tweaks/fixes to readme
jcasimir authored Jul 27, 2011
304 def published_at
b050cd3 @jcasimir Revising README for 0.9.1 with named accessors
jcasimir authored Oct 20, 2011
305 date = h.content_tag(:span, article.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
306 time = h.content_tag(:span, article.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
34f14ff @jcasimir Fixing inconsistencies in the Readme
jcasimir authored Jul 27, 2011
307 h.content_tag :span, date + time, :class => 'published_at'
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
308 end
309 end
310 ```
138e034 @jpfuentes2 Add example of decorates_association to Readme
jpfuentes2 authored Feb 10, 2012
311
312 ### Example of Decorated Associations
313
314 Add a `decorates_association :association_name` to gain access to a decorated version of your target association.
315
316 ```ruby
f1bd79b @steveklabnik Updating README.
steveklabnik authored May 11, 2012
317 class ArticleDecorator < Draper::Base
138e034 @jpfuentes2 Add example of decorates_association to Readme
jpfuentes2 authored Feb 10, 2012
318 decorates :article
319 decorates_association :author # belongs_to :author association
320 end
321
f1bd79b @steveklabnik Updating README.
steveklabnik authored May 11, 2012
322 class AuthorDecorator < Draper::Base
138e034 @jpfuentes2 Add example of decorates_association to Readme
jpfuentes2 authored Feb 10, 2012
323 decorates :author
324
325 def fancy_name
326 "#{model.title}. #{model.first_name} #{model.middle_name[0]}. #{model.last_name}"
327 end
328 end
329 ```
330
331 Now when you call the association it will use a decorator.
332
333 ```ruby
334 <%= @article.author.fancy_name %>
335 ```
336
eae7c6d @avdgaag Added note about preloading issues to Readme
avdgaag authored May 15, 2012
337 ### A note on Rails configuration
338
339 Draper loads your application's decorators when Rails start. This may lead to an issue with configuring I18n, whereby the settings you provide in `./config/application.rb` are ignored. This happens when you use the `I18n` constant at the class-level in one of the models that have a decorator, as in the following example:
340
341 ```ruby
342 # app/models/user.rb
343 class User < ActiveRecord::Base
344 validates :email, presence: { message: I18n.t('invalid_email') }
345 end
346
347 # app/decorators/user_decorator.rb
348 class UserDecorator < ApplicationDecorator
349 decorates :user
350 end
351 ```
352
353 Note how the `validates` line is executed when the `User` class is loaded, triggering the initialization of the I18n framework _before_ Rails had a chance to apply its configuration.
354
355 Using `I18n` directly in your model definition **is an antipattern**. The preferred solution would be to not override the `message` option in your `validates` macro, but provide the `activerecord.errors.models.attributes.user.email.presence` key in your translation files.
356
860fb06 @steveklabnik Add note about decorates_before_rendering.
steveklabnik authored Aug 11, 2012
357 ## Extension gems
358
359 For automatic decoration, check out [decorates_before_rendering](https://github.com/ohwillie/decorates_before_rendering).
360
eb57738 @patriciomacadden adding the "Contributing" section to the readme
patriciomacadden authored Apr 9, 2012
361 ## Contributing
362
363 1. Fork it.
364 2. Create a branch (`git checkout -b my_awesome_branch`)
365 3. Commit your changes (`git commit -am "Added some magic"`)
366 4. Push to the branch (`git push origin my_awesome_branch`)
367 5. Send pull request
368
d983661 @jcasimir Add contributors section
jcasimir authored Oct 5, 2012
369 ## Contributors
370
160d379 @jcasimir "i" before "e" except after "c"
jcasimir authored Oct 5, 2012
371 Draper was conceived by Jeff Casimir and heavily refined by Steve Klabnik and a great community of open source contributors.
d983661 @jcasimir Add contributors section
jcasimir authored Oct 5, 2012
372
373 ### Core Team
374
375 * Jeff Casimir (jeff@jumpstartlab.com)
376 * Steve Klabnik (steve@jumpstartlab.com)
9966b85 @jcasimir Add @nashby to the Core Team list
jcasimir authored Oct 5, 2012
377 * Vasiliy Ermolovich
d983661 @jcasimir Add contributors section
jcasimir authored Oct 5, 2012
378
a3804b0 @jcasimir Bring over generator structure from rails_decorators
jcasimir authored Jun 30, 2011
379 ## License
380
381 (The MIT License)
382
383 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
384
385 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
386
4b52813 @melriffe Added blurb about turning off the automatic calling of the helper gen…
melriffe authored Jul 29, 2011
387 THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Something went wrong with that request. Please try again.