draper 0.18.0 → 1.1.0

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.
Files changed (155) hide show
  1. data/.gitignore +3 -0
  2. data/.travis.yml +11 -0
  3. data/.yardopts +1 -1
  4. data/CHANGELOG.md +164 -0
  5. data/CONTRIBUTING.md +15 -0
  6. data/Gemfile +34 -0
  7. data/LICENSE +7 -0
  8. data/README.md +416 -0
  9. data/Rakefile +53 -31
  10. data/draper.gemspec +11 -9
  11. data/lib/draper/automatic_delegation.rb +50 -0
  12. data/lib/draper/collection_decorator.rb +107 -0
  13. data/lib/draper/decoratable/equality.rb +14 -0
  14. data/lib/draper/decoratable.rb +79 -0
  15. data/lib/draper/decorated_association.rb +74 -0
  16. data/lib/draper/decorator.rb +235 -0
  17. data/lib/draper/delegation.rb +13 -0
  18. data/lib/draper/finders.rb +37 -0
  19. data/lib/draper/helper_proxy.rb +36 -0
  20. data/lib/draper/lazy_helpers.rb +10 -6
  21. data/lib/draper/railtie.rb +27 -21
  22. data/lib/draper/tasks/test.rake +22 -0
  23. data/lib/draper/test/devise_helper.rb +30 -0
  24. data/lib/draper/test/minitest_integration.rb +2 -3
  25. data/lib/draper/test/rspec_integration.rb +7 -13
  26. data/lib/draper/test_case.rb +53 -0
  27. data/lib/draper/version.rb +1 -1
  28. data/lib/draper/view_context/build_strategy.rb +48 -0
  29. data/lib/draper/view_context.rb +81 -24
  30. data/lib/draper/view_helpers.rb +37 -0
  31. data/lib/draper.rb +50 -8
  32. data/lib/generators/decorator/decorator_generator.rb +10 -2
  33. data/lib/generators/decorator/templates/decorator.rb +12 -27
  34. data/lib/generators/mini_test/decorator_generator.rb +20 -0
  35. data/lib/generators/mini_test/templates/decorator_spec.rb +4 -0
  36. data/lib/generators/mini_test/templates/decorator_test.rb +4 -0
  37. data/lib/generators/test_unit/templates/decorator_test.rb +1 -1
  38. data/spec/draper/collection_decorator_spec.rb +259 -0
  39. data/spec/draper/decoratable/equality_spec.rb +10 -0
  40. data/spec/draper/decoratable_spec.rb +167 -0
  41. data/spec/draper/decorated_association_spec.rb +145 -0
  42. data/spec/draper/decorator_spec.rb +598 -0
  43. data/spec/draper/finders_spec.rb +166 -0
  44. data/spec/draper/helper_proxy_spec.rb +42 -0
  45. data/spec/draper/view_context/build_strategy_spec.rb +116 -0
  46. data/spec/draper/view_context_spec.rb +154 -0
  47. data/spec/draper/view_helpers_spec.rb +8 -0
  48. data/spec/dummy/.rspec +2 -0
  49. data/spec/dummy/Rakefile +7 -0
  50. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  51. data/spec/dummy/app/controllers/localized_urls.rb +5 -0
  52. data/spec/dummy/app/controllers/posts_controller.rb +18 -0
  53. data/spec/dummy/app/decorators/post_decorator.rb +56 -0
  54. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  55. data/spec/dummy/app/mailers/application_mailer.rb +3 -0
  56. data/spec/dummy/app/mailers/post_mailer.rb +19 -0
  57. data/spec/dummy/app/models/admin.rb +5 -0
  58. data/spec/dummy/app/models/mongoid_post.rb +5 -0
  59. data/spec/dummy/app/models/post.rb +3 -0
  60. data/spec/dummy/app/models/user.rb +5 -0
  61. data/spec/dummy/app/views/layouts/application.html.erb +11 -0
  62. data/spec/dummy/app/views/post_mailer/decorated_email.html.erb +1 -0
  63. data/spec/dummy/app/views/posts/_post.html.erb +34 -0
  64. data/spec/dummy/app/views/posts/show.html.erb +1 -0
  65. data/spec/dummy/bin/rails +4 -0
  66. data/spec/dummy/config/application.rb +70 -0
  67. data/spec/dummy/config/boot.rb +5 -0
  68. data/spec/dummy/config/database.yml +25 -0
  69. data/spec/dummy/config/environment.rb +5 -0
  70. data/spec/dummy/config/environments/development.rb +33 -0
  71. data/spec/dummy/config/environments/production.rb +57 -0
  72. data/spec/dummy/config/environments/test.rb +31 -0
  73. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  74. data/spec/dummy/config/initializers/inflections.rb +15 -0
  75. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  76. data/spec/dummy/config/initializers/secret_token.rb +8 -0
  77. data/spec/dummy/config/initializers/session_store.rb +8 -0
  78. data/spec/dummy/config/locales/en.yml +5 -0
  79. data/spec/dummy/config/mongoid.yml +80 -0
  80. data/spec/dummy/config/routes.rb +9 -0
  81. data/spec/dummy/config.ru +4 -0
  82. data/spec/dummy/db/migrate/20121019115657_create_posts.rb +8 -0
  83. data/spec/dummy/db/schema.rb +21 -0
  84. data/spec/dummy/db/seeds.rb +2 -0
  85. data/spec/dummy/fast_spec/post_decorator_spec.rb +38 -0
  86. data/spec/dummy/lib/tasks/test.rake +16 -0
  87. data/spec/dummy/log/.gitkeep +0 -0
  88. data/spec/dummy/public/404.html +26 -0
  89. data/spec/dummy/public/422.html +26 -0
  90. data/spec/dummy/public/500.html +25 -0
  91. data/spec/dummy/public/favicon.ico +0 -0
  92. data/spec/dummy/script/rails +6 -0
  93. data/spec/dummy/spec/decorators/devise_spec.rb +64 -0
  94. data/spec/dummy/spec/decorators/helpers_spec.rb +21 -0
  95. data/spec/dummy/spec/decorators/post_decorator_spec.rb +46 -0
  96. data/spec/dummy/spec/decorators/spec_type_spec.rb +7 -0
  97. data/spec/dummy/spec/decorators/view_context_spec.rb +22 -0
  98. data/spec/dummy/spec/mailers/post_mailer_spec.rb +33 -0
  99. data/spec/dummy/spec/models/mongoid_post_spec.rb +10 -0
  100. data/spec/dummy/spec/models/post_spec.rb +14 -0
  101. data/spec/dummy/spec/spec_helper.rb +9 -0
  102. data/spec/dummy/test/decorators/minitest/devise_test.rb +64 -0
  103. data/spec/dummy/test/decorators/minitest/helpers_test.rb +21 -0
  104. data/spec/dummy/test/decorators/minitest/spec_type_test.rb +52 -0
  105. data/spec/dummy/test/decorators/minitest/view_context_test.rb +24 -0
  106. data/spec/dummy/test/decorators/test_unit/devise_test.rb +64 -0
  107. data/spec/dummy/test/decorators/test_unit/helpers_test.rb +21 -0
  108. data/spec/dummy/test/decorators/test_unit/view_context_test.rb +24 -0
  109. data/spec/dummy/test/minitest_helper.rb +4 -0
  110. data/spec/dummy/test/test_helper.rb +3 -0
  111. data/spec/generators/decorator/decorator_generator_spec.rb +48 -7
  112. data/spec/integration/integration_spec.rb +58 -0
  113. data/{performance → spec/performance}/decorators.rb +2 -4
  114. data/spec/spec_helper.rb +25 -43
  115. data/spec/support/dummy_app.rb +85 -0
  116. data/spec/support/matchers/have_text.rb +50 -0
  117. data/spec/support/shared_examples/decoratable_equality.rb +40 -0
  118. data/spec/support/shared_examples/view_helpers.rb +39 -0
  119. metadata +253 -87
  120. data/CHANGELOG.markdown +0 -57
  121. data/Readme.markdown +0 -387
  122. data/lib/draper/active_model_support.rb +0 -27
  123. data/lib/draper/base.rb +0 -312
  124. data/lib/draper/decorated_enumerable_proxy.rb +0 -90
  125. data/lib/draper/model_support.rb +0 -25
  126. data/lib/draper/rspec_integration.rb +0 -2
  127. data/lib/draper/system.rb +0 -18
  128. data/spec/draper/base_spec.rb +0 -873
  129. data/spec/draper/decorated_enumerable_proxy_spec.rb +0 -45
  130. data/spec/draper/model_support_spec.rb +0 -48
  131. data/spec/minitest-rails/spec_type_spec.rb +0 -63
  132. data/spec/support/samples/active_record.rb +0 -17
  133. data/spec/support/samples/decorator.rb +0 -5
  134. data/spec/support/samples/decorator_with_allows.rb +0 -3
  135. data/spec/support/samples/decorator_with_application_helper.rb +0 -25
  136. data/spec/support/samples/decorator_with_denies.rb +0 -3
  137. data/spec/support/samples/decorator_with_denies_all.rb +0 -3
  138. data/spec/support/samples/decorator_with_multiple_allows.rb +0 -4
  139. data/spec/support/samples/decorator_with_special_methods.rb +0 -13
  140. data/spec/support/samples/enumerable_proxy.rb +0 -3
  141. data/spec/support/samples/namespaced_product.rb +0 -51
  142. data/spec/support/samples/namespaced_product_decorator.rb +0 -7
  143. data/spec/support/samples/non_active_model_product.rb +0 -2
  144. data/spec/support/samples/product.rb +0 -80
  145. data/spec/support/samples/product_decorator.rb +0 -7
  146. data/spec/support/samples/products_decorator.rb +0 -10
  147. data/spec/support/samples/sequel_product.rb +0 -13
  148. data/spec/support/samples/some_thing.rb +0 -2
  149. data/spec/support/samples/some_thing_decorator.rb +0 -3
  150. data/spec/support/samples/specific_product_decorator.rb +0 -4
  151. data/spec/support/samples/widget.rb +0 -2
  152. data/spec/support/samples/widget_decorator.rb +0 -2
  153. /data/{performance → spec/performance}/active_record.rb +0 -0
  154. /data/{performance/bechmark.rb → spec/performance/benchmark.rb} +0 -0
  155. /data/{performance → spec/performance}/models.rb +0 -0
data/Readme.markdown DELETED
@@ -1,387 +0,0 @@
1
- # Draper: View Models for Rails
2
-
3
- [![TravisCI Build Status](https://secure.travis-ci.org/jcasimir/draper.png)](http://travis-ci.org/jcasimir/draper)
4
-
5
- ## Quick Start
6
-
7
- 1. Add `gem 'draper'` to your `Gemfile` and `bundle`
8
- 2. When you generate a resource with `rails g resource YourModel`, you get a decorator automatically!
9
- 3. If `YourModel` already exists, run `rails g decorator YourModel` to create `YourModelDecorator`
10
- 4. Edit `app/decorators/[your_model]_decorator.rb` using:
11
- 1. `h` to proxy to Rails/application helpers like `h.current_user`
12
- 2. the name of your decorated model to access the wrapped object like `article.created_at`
13
- 5. Wrap models in your controller with the decorator using:
14
- 1. `.find` automatic lookup & wrap
15
- ex: `ArticleDecorator.find(1)`
16
- 2. `.decorate` method with a single object or collection,
17
- ex: `ArticleDecorator.decorate(Article.all)`
18
- 3. `.new` method with single object
19
- ex: `ArticleDecorator.new(Article.first)`
20
- 6. Call decorator methods from your view templates
21
- ex: `<%= @article_decorator.created_at %>`
22
-
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
-
33
- ## Goals
34
-
35
- This gem makes it easy to apply the decorator pattern to domain models in a Rails application. This pattern gives you three wins:
36
-
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.
40
-
41
- ### 1. Object Oriented Helpers
42
-
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.
44
-
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:
46
-
47
- ```ruby
48
- class ArticleDecorator < Draper::Base
49
- decorates :article
50
-
51
- def published_at
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(" ")
54
- h.content_tag :span, date + time, :class => 'created_at'
55
- end
56
- end
57
- ```
58
-
59
- ### 2. View-Layer Data Filtering
60
-
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?
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
-
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:
68
-
69
- ```ruby
70
- class ArticleDecorator < ApplicationDecorator
71
- decorates :article
72
-
73
- ADMIN_VISIBLE_ATTRIBUTES = [:title, :body, :author, :status]
74
- PUBLIC_VISIBLE_ATTRIBUTES = [:title, :body]
75
-
76
- def to_json
77
- attr_set = h.current_user.admin? ? ADMIN_VISIBLE_ATTRIBUTES : PUBLIC_VISIBLE_ATTRIBUTES
78
- article.to_json(:only => attr_set)
79
- end
80
- end
81
- ```
82
-
83
- ### 3. Enforcing an Interface
84
-
85
- Want to strictly control what methods are proxied to the original object? Use `denies` or `allows`.
86
-
87
- #### Using `denies`
88
-
89
- The `denies` method takes a blacklist approach. For instance:
90
-
91
- ```ruby
92
- class ArticleDecorator < ApplicationDecorator
93
- decorates :article
94
- denies :title
95
- end
96
- ```
97
-
98
- Then, to test it:
99
-
100
- ```irb
101
- > ad = ArticleDecorator.find(1)
102
- => #<ArticleDecorator:0x000001020d7728 @model=#<Article id: 1, title: "Hello, World">>
103
- > ad.title
104
- NoMethodError: undefined method `title' for #<ArticleDecorator:0x000001020d7728>
105
- ```
106
-
107
- #### Using `allows`
108
-
109
- A better approach is to define a whitelist using `allows`:
110
-
111
- ```ruby
112
- class ArticleDecorator < ApplicationDecorator
113
- decorates :article
114
- allows :title, :description
115
- end
116
- ```
117
-
118
- ```irb
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
124
- NoMethodError: undefined method `created_at' for #<ArticleDecorator:0x000001020d7728>
125
- ```
126
-
127
- ## Up and Running
128
-
129
- ### Setup
130
-
131
- Add the dependency to your `Gemfile`:
132
-
133
- ```
134
- gem "draper"
135
- ```
136
-
137
- Then run `bundle` from the project directory.
138
-
139
- ### Generate the Decorator
140
-
141
- To decorate a model named `Article`:
142
-
143
- ```
144
- rails generate decorator article
145
- ```
146
-
147
- ### Writing Methods
148
-
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:
150
-
151
- ```ruby
152
- class ArticleDecorator < Draper::Base
153
- decorates :article
154
-
155
- def author_name
156
- article.author.first_name + " " + article.author.last_name
157
- end
158
- end
159
- ```
160
-
161
- ### Using Existing Helpers
162
-
163
- You probably want to make use of Rails helpers and those defined in your application. Use the `helpers` or `h` method proxy:
164
-
165
- ```ruby
166
- class ArticleDecorator < Draper::Base
167
- decorates :article
168
-
169
- def published_at
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(" ")
172
- h.content_tag :span, date + time, :class => 'created_at'
173
- end
174
- end
175
- ```
176
-
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
182
- class ArticleDecorator < Draper::Base
183
- decorates :article
184
- include Draper::LazyHelpers
185
-
186
- def published_at
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(" ")
189
- content_tag :span, date + time, :class => 'created_at'
190
- end
191
- end
192
- ```
193
-
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
-
200
- ```ruby
201
- ArticleDecorator.new(Article.find(params[:id]))
202
- ```
203
-
204
- * Call `.decorate` and pass in an object or collection of objects to be wrapped:
205
-
206
- ```ruby
207
- ArticleDecorator.decorate(Article.first) # Returns one instance of ArticleDecorator
208
- ArticleDecorator.decorate(Article.all) # Returns an enumeration proxy of ArticleDecorator instances
209
- ```
210
-
211
- * Call `.find` to automatically do a lookup on the `decorates` class:
212
-
213
- ```ruby
214
- ArticleDecorator.find(1)
215
- ```
216
-
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
- ```
224
-
225
- ### Integration with RSpec
226
-
227
- Using the provided generator, Draper will place specs for your new decorator in `spec/decorators/`.
228
-
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.
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.
232
-
233
- Note: If you're using Spork, you need to `require 'draper/test/rspec_integration'` in your Spork.prefork block.
234
-
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
-
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
250
-
251
- For a brief tutorial with sample project, check this out: http://tutorials.jumpstartlab.com/topics/decorators.html
252
-
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
-
264
- First, follow the steps above to add the dependency and update your bundle.
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
- ```
269
- rails generate decorator Article
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
275
- def published_at
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')
278
- h.content_tag :span, date + time, :class => 'published_at'
279
- end
280
- ```
281
-
282
- Then you need to perform the wrapping in your controller. Here's the simplest method:
283
-
284
- ```ruby
285
- class ArticlesController < ApplicationController
286
- def show
287
- @article = ArticleDecorator.find params[:id]
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
295
- <%= @article.published_at %>
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
301
- class ArticleDecorator < Draper::Base
302
- decorates :article
303
-
304
- def published_at
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(" ")
307
- h.content_tag :span, date + time, :class => 'published_at'
308
- end
309
- end
310
- ```
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
317
- class ArticleDecorator < Draper::Base
318
- decorates :article
319
- decorates_association :author # belongs_to :author association
320
- end
321
-
322
- class AuthorDecorator < Draper::Base
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
-
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
-
357
- ## Extension gems
358
-
359
- For automatic decoration, check out [decorates_before_rendering](https://github.com/ohwillie/decorates_before_rendering).
360
-
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
-
369
- ## Contributors
370
-
371
- Draper was conceived by Jeff Casimir and heavily refined by Steve Klabnik and a great community of open source contributors.
372
-
373
- ### Core Team
374
-
375
- * Jeff Casimir (jeff@jumpstartlab.com)
376
- * Steve Klabnik (steve@jumpstartlab.com)
377
- * Vasiliy Ermolovich
378
-
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
-
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.
@@ -1,27 +0,0 @@
1
- module Draper::ActiveModelSupport
2
- module Proxies
3
- def self.extended(base)
4
- # These methods (as keys) will be created only if the correspondent
5
- # model responds to the method
6
- proxies = [:to_param, :errors, :id]
7
-
8
- proxies.each do |method_name|
9
- if base.model.respond_to?(method_name)
10
- base.singleton_class.class_eval do
11
- if !base.class.instance_methods.include?(method_name) || base.class.instance_method(method_name).owner === Draper::Base
12
- define_method(method_name) do |*args, &block|
13
- model.send(method_name, *args, &block)
14
- end
15
- end
16
- end
17
- end
18
- end
19
-
20
- base.class_eval do
21
- def to_model
22
- self
23
- end
24
- end
25
- end
26
- end
27
- end