draper 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,7 +8,7 @@
8
8
  2. Run `rails g draper:decorator YourModel`
9
9
  3. Edit `app/decorators/[your_model]_decorator.rb` using:
10
10
  1. `h` to proxy to Rails/application helpers like `h.current_user`
11
- 2. `model` to access the wrapped object like `model.created_at`
11
+ 2. `[your_model]` to access the wrapped object like `article.created_at`
12
12
  4. Put common decorations in `app/decorators/application.rb`
13
13
  5. Wrap models in your controller with the decorator using:
14
14
  1. `.find` automatic lookup & wrap
@@ -20,6 +20,17 @@
20
20
  6. Output the instance methods in your view templates
21
21
  ex: `@article_decorator.created_at`
22
22
 
23
+ ## What's New
24
+
25
+ ### Version 0.9.1
26
+
27
+ * Automatically generate a named accessor for the wrapped object, so now inside of `ArticleDecorator` you can use `article` instead of just `model`
28
+ * Removed the `lazy_helpers` method to favor using `include Draper::LazyHelpers`
29
+ * Refactored how methods are selected for delegation to the wrapped model
30
+ * Fixed how the view context is stored in the `Thread.current` to resolve cross-request issues
31
+ * Decorated collections now return a collection proxy instead of an array, which fixes many compatibility issues
32
+ * Automatically generate `RSpec` stub for decorators [PENDING: Make this work properly for `Test::Unit` -- help?]
33
+
23
34
  ## Goals
24
35
 
25
36
  This gem makes it easy to apply the decorator pattern to domain models in a Rails application. This pattern gives you three wins:
@@ -38,8 +49,8 @@ A decorator wraps an object with presentation-related accessor methods. For inst
38
49
  class ArticleDecorator < ApplicationDecorator
39
50
  decorates :article
40
51
  def published_at
41
- date = h.content_tag(:span, model.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
42
- time = h.content_tag(:span, model.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
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(" ")
43
54
  h.content_tag :span, date + time, :class => 'created_at'
44
55
  end
45
56
  end
@@ -63,7 +74,7 @@ class ArticleDecorator < ApplicationDecorator
63
74
 
64
75
  def to_json
65
76
  attr_set = h.current_user.admin? ? ADMIN_VISIBLE_ATTRIBUTES : PUBLIC_VISIBLE_ATTRIBUTES
66
- model.to_json(:only => attr_set)
77
+ article.to_json(:only => attr_set)
67
78
  end
68
79
  end
69
80
  ```
@@ -122,36 +133,7 @@ Add the dependency to your `Gemfile`:
122
133
  gem "draper"
123
134
  ```
124
135
 
125
- Run bundle:
126
-
127
- ```
128
- bundle
129
- ```
130
-
131
- #### Disable Rails Helper Generation (Optional)
132
-
133
- When you generate a scaffold, Rails will create a matching helper file. If you're using decorators, this is probably unnecessary. You can disable the helper file creation by adding this to your `config/application.rb`
134
-
135
- ```ruby
136
- config.generators do |g|
137
- g.helper false
138
- end
139
- ```
140
- If you want a helper, you can still call `rails generate helper` directly.
141
-
142
-
143
- #### Add DecoratorGenerator to ActiveRecord Generator (Optional)
144
-
145
- Add the following to your `config/application.rb`
146
-
147
- ```ruby
148
- config.generators do |g|
149
- g.orm :decorator, :invoke_after_finished => "active_record:model"
150
- end
151
- ```
152
-
153
- From now on, every model you generate will first invoke the DecoratorGenerator. The Decorator will then invoke the active_record:model Generator.
154
-
136
+ Then run `bundle` from the project directory.
155
137
 
156
138
  ### Generate the Decorator
157
139
 
@@ -163,14 +145,14 @@ rails generate draper:decorator Article
163
145
 
164
146
  ### Writing Methods
165
147
 
166
- Open the decorator model (ex: `app/decorators/article_decorator.rb`) and add normal instance methods. To access the wrapped source object, use the `model` method:
148
+ 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:
167
149
 
168
150
  ```ruby
169
151
  class ArticleDecorator < ApplicationDecorator
170
152
  decorates :article
171
153
 
172
154
  def author_name
173
- model.author.first_name + " " + model.author.last_name
155
+ article.author.first_name + " " + article.author.last_name
174
156
  end
175
157
  end
176
158
  ```
@@ -184,8 +166,8 @@ class ArticleDecorator < ApplicationDecorator
184
166
  decorates :article
185
167
 
186
168
  def published_at
187
- date = h.content_tag(:span, model.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
188
- time = h.content_tag(:span, model.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
169
+ date = h.content_tag(:span, article.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
170
+ time = h.content_tag(:span, article.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
189
171
  h.content_tag :span, date + time, :class => 'created_at'
190
172
  end
191
173
  end
@@ -201,8 +183,8 @@ class ArticleDecorator < ApplicationDecorator
201
183
  include Draper::LazyHelpers
202
184
 
203
185
  def published_at
204
- date = content_tag(:span, model.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
205
- time = content_tag(:span, model.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
186
+ date = content_tag(:span, article.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
187
+ time = content_tag(:span, article.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
206
188
  content_tag :span, date + time, :class => 'created_at'
207
189
  end
208
190
  end
@@ -222,7 +204,7 @@ ArticleDecorator.new(Article.find(params[:id]))`
222
204
 
223
205
  ```ruby
224
206
  ArticleDecorator.decorate(Article.first) # Returns one instance of ArticleDecorator
225
- ArticleDecorator.decorate(Article.all) # Returns an array of ArticleDecorator instances
207
+ ArticleDecorator.decorate(Article.all) # Returns an enumeration proxy of ArticleDecorator instances
226
208
  ```
227
209
 
228
210
  * Call `.find` to do automatically do a lookup on the `decorates` class:
@@ -274,8 +256,8 @@ Now open up the created `app/decorators/article_decorator.rb` and you'll find an
274
256
 
275
257
  ```ruby
276
258
  def published_at
277
- date = h.content_tag(:span, model.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
278
- time = h.content_tag(:span, model.published_at.strftime("%l:%M%p").delete(" "), :class => 'time')
259
+ date = h.content_tag(:span, article.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
260
+ time = h.content_tag(:span, article.published_at.strftime("%l:%M%p").delete(" "), :class => 'time')
279
261
  h.content_tag :span, date + time, :class => 'published_at'
280
262
  end
281
263
  ```
@@ -303,8 +285,8 @@ class ArticleDecorator < ApplicationDecorator
303
285
  decorates :article
304
286
 
305
287
  def published_at
306
- date = h.content_tag(:span, model.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
307
- time = h.content_tag(:span, model.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
288
+ date = h.content_tag(:span, article.published_at.strftime("%A, %B %e").squeeze(" "), :class => 'date')
289
+ time = h.content_tag(:span, article.published_at.strftime("%l:%M%p"), :class => 'time').delete(" ")
308
290
  h.content_tag :span, date + time, :class => 'published_at'
309
291
  end
310
292
  end
@@ -317,8 +299,6 @@ end
317
299
  * Add information about the `.decorator` method
318
300
  * Make clear the pattern of overriding accessor methods of the wrapped model
319
301
  * Build sample Rails application(s)
320
- * Add a short screencast
321
- * Add YARD documentation to source
322
302
  * Add a section about contributing
323
303
  * Generators
324
304
  * Implement hook so generating a controller/scaffold generates a decorator
@@ -51,6 +51,7 @@ module Draper
51
51
  def self.decorates(input)
52
52
  self.model_class = input.to_s.camelize.constantize
53
53
  model_class.send :include, Draper::ModelSupport
54
+ define_method(input){ @model }
54
55
  end
55
56
 
56
57
  # Specifies a black list of methods which may *not* be proxied to
@@ -1,3 +1,3 @@
1
1
  module Draper
2
- VERSION = "0.9.0"
2
+ VERSION = "0.9.1"
3
3
  end
@@ -40,6 +40,11 @@ describe Draper::Base do
40
40
  BusinessDecorator.model_class.should == Business
41
41
  end.should_not raise_error
42
42
  end
43
+
44
+ it "creates a named accessor for the wrapped model" do
45
+ pd = ProductDecorator.new(source)
46
+ pd.send(:product).should == source
47
+ end
43
48
  end
44
49
 
45
50
  context(".model / .to_model") do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: draper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: