draper 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: