draper 3.0.0 → 3.0.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.
- checksums.yaml +4 -4
- data/.travis.yml +9 -2
- data/CHANGELOG.md +5 -0
- data/README.md +9 -0
- data/lib/draper/compatibility/global_id.rb +22 -0
- data/lib/draper/decoratable.rb +6 -6
- data/lib/draper/decorator.rb +14 -10
- data/lib/draper/version.rb +1 -1
- data/lib/generators/draper/install_generator.rb +1 -1
- data/lib/generators/mini_test/decorator_generator.rb +1 -1
- data/lib/generators/rails/decorator_generator.rb +1 -1
- data/lib/generators/rspec/decorator_generator.rb +6 -4
- data/lib/generators/test_unit/decorator_generator.rb +7 -4
- data/spec/draper/decoratable_spec.rb +23 -1
- data/spec/draper/decorator_spec.rb +3 -2
- data/spec/dummy/app/jobs/publish_post_job.rb +7 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/post.rb +1 -1
- data/spec/dummy/config/application.rb +0 -3
- data/spec/dummy/config/environments/test.rb +2 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/db/migrate/20121019115657_create_posts.rb +1 -1
- data/spec/dummy/spec/jobs/publish_post_job_spec.rb +9 -0
- data/spec/dummy/spec/models/application_spec.rb +7 -0
- data/spec/dummy/spec/models/post_spec.rb +11 -2
- data/spec/spec_helper.rb +2 -0
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc23ed0f81227aa958510ecb67676453d97b40cc
|
4
|
+
data.tar.gz: ed8a159772bafb7df87cc5c767757e8b697f55b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 466c609e53461c1e1f260f9e2bf6a0eb522238e5bdae8a2f37a88c1cd22d22665bf18293ba497f9f64d27faa0e12f0dbb9e3d906bae569f324c6124c02ad6b7e
|
7
|
+
data.tar.gz: db229fe0cf5daf0acc2e52834c599a21e9ba85782458a8fd3a0520574e77f1857ec30c57c81dceb75561016170c941f8da3593d3a58fd395137c01ce57322cf0
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Draper Changelog
|
2
2
|
|
3
|
+
## 3.0.1
|
4
|
+
* Let `decorator_class` infer anonymous class decorator from superclass [#820](https://github.com/drapergem/draper/pull/820)
|
5
|
+
* When inferring decorator fails, show original class instead of `ActiveRecord::Base` [#821](https://github.com/drapergem/draper/pull/821)
|
6
|
+
* ActiveJob compatibility and documentation [#817](https://github.com/drapergem/draper/pull/817)
|
7
|
+
|
3
8
|
## 3.0.0 - 2017
|
4
9
|
|
5
10
|
### Breaking Changes
|
data/README.md
CHANGED
@@ -618,6 +618,15 @@ is included in `ActiveRecord::Base` and `Mongoid::Document` by default. If
|
|
618
618
|
you're using another ORM, or want to decorate plain old Ruby objects,
|
619
619
|
you can include this module manually.
|
620
620
|
|
621
|
+
### Active Job Integration
|
622
|
+
|
623
|
+
[Active Job](http://edgeguides.rubyonrails.org/active_job_basics.html) allows you to pass ActiveRecord
|
624
|
+
objects to background tasks directly and performs the necessary serialization and deserialization. In
|
625
|
+
order to do this, arguments to a background job must implement [Global ID](https://github.com/rails/globalid).
|
626
|
+
Decorated objects implement Global ID by delegating to the object they are decorating. This means
|
627
|
+
you can pass decorated objects to background jobs, however, the object won't be decorated when it is
|
628
|
+
deserialized.
|
629
|
+
|
621
630
|
## Contributors
|
622
631
|
|
623
632
|
Draper was conceived by Jeff Casimir and heavily refined by Steve Klabnik and a
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Draper
|
2
|
+
module Compatibility
|
3
|
+
# [Active Job](http://edgeguides.rubyonrails.org/active_job_basics.html) allows you to pass
|
4
|
+
# ActiveRecord objects to background tasks directly and performs the necessary serialization
|
5
|
+
# and deserialization. In order to do this, arguments to a background job must implement
|
6
|
+
# [Global ID](https://github.com/rails/globalid).
|
7
|
+
#
|
8
|
+
# This compatibility patch implements Global ID for decorated objects by delegating to the object
|
9
|
+
# that is decorated. This means you can pass decorated objects to background jobs, but
|
10
|
+
# the object won't be decorated when it is deserialized. This patch is meant as an intermediate
|
11
|
+
# fix until we can find a way to deserialize the decorated object correctly.
|
12
|
+
module GlobalID
|
13
|
+
extend ActiveSupport::Concern
|
14
|
+
|
15
|
+
included do
|
16
|
+
include ::GlobalID::Identification
|
17
|
+
|
18
|
+
delegate :to_global_id, :to_signed_global_id, to: :object
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/draper/decoratable.rb
CHANGED
@@ -69,16 +69,16 @@ module Draper
|
|
69
69
|
# `Product` maps to `ProductDecorator`).
|
70
70
|
#
|
71
71
|
# @return [Class] the inferred decorator class.
|
72
|
-
def decorator_class
|
72
|
+
def decorator_class(called_on = self)
|
73
73
|
prefix = respond_to?(:model_name) ? model_name : name
|
74
74
|
decorator_name = "#{prefix}Decorator"
|
75
|
-
decorator_name.
|
76
|
-
|
77
|
-
|
75
|
+
decorator_name_constant = decorator_name.safe_constantize
|
76
|
+
return decorator_name_constant unless decorator_name_constant.nil?
|
77
|
+
|
78
78
|
if superclass.respond_to?(:decorator_class)
|
79
|
-
superclass.decorator_class
|
79
|
+
superclass.decorator_class(called_on)
|
80
80
|
else
|
81
|
-
raise Draper::UninferrableDecoratorError.new(
|
81
|
+
raise Draper::UninferrableDecoratorError.new(called_on)
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
data/lib/draper/decorator.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
require 'draper/compatibility/global_id'
|
2
|
+
|
1
3
|
module Draper
|
2
4
|
class Decorator
|
3
5
|
include Draper::ViewHelpers
|
6
|
+
include Draper::Compatibility::GlobalID if defined?(GlobalID)
|
4
7
|
extend Draper::Delegation
|
5
8
|
|
6
9
|
include ActiveModel::Serialization
|
@@ -222,9 +225,9 @@ module Draper
|
|
222
225
|
# @return [Class] the class created by {decorate_collection}.
|
223
226
|
def self.collection_decorator_class
|
224
227
|
name = collection_decorator_name
|
225
|
-
name.
|
226
|
-
|
227
|
-
Draper::CollectionDecorator
|
228
|
+
name_constant = name && name.safe_constantize
|
229
|
+
|
230
|
+
name_constant || Draper::CollectionDecorator
|
228
231
|
end
|
229
232
|
|
230
233
|
private
|
@@ -239,22 +242,23 @@ module Draper
|
|
239
242
|
end
|
240
243
|
|
241
244
|
def self.object_class_name
|
242
|
-
|
245
|
+
return nil if name.nil? || name.demodulize !~ /.+Decorator$/
|
243
246
|
name.chomp("Decorator")
|
244
247
|
end
|
245
248
|
|
246
249
|
def self.inferred_object_class
|
247
250
|
name = object_class_name
|
248
|
-
name.
|
249
|
-
|
250
|
-
|
251
|
+
name_constant = name && name.safe_constantize
|
252
|
+
return name_constant unless name_constant.nil?
|
253
|
+
|
251
254
|
raise Draper::UninferrableObjectError.new(self)
|
252
255
|
end
|
253
256
|
|
254
257
|
def self.collection_decorator_name
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
+
singular = object_class_name
|
259
|
+
plural = singular && singular.pluralize
|
260
|
+
|
261
|
+
"#{plural}Decorator" unless plural == singular
|
258
262
|
end
|
259
263
|
|
260
264
|
def handle_multiple_decoration(options)
|
data/lib/draper/version.rb
CHANGED
@@ -4,7 +4,7 @@ module MiniTest
|
|
4
4
|
module Generators
|
5
5
|
class DecoratorGenerator < Base
|
6
6
|
def self.source_root
|
7
|
-
File.expand_path(
|
7
|
+
File.expand_path("templates", __dir__)
|
8
8
|
end
|
9
9
|
|
10
10
|
class_option :spec, type: :boolean, default: false, desc: "Use MiniTest::Spec DSL"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Rails
|
2
2
|
module Generators
|
3
3
|
class DecoratorGenerator < NamedBase
|
4
|
-
source_root File.expand_path("
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
5
5
|
check_class_collision suffix: "Decorator"
|
6
6
|
|
7
7
|
class_option :parent, type: :string, desc: "The parent class for the generated decorator"
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module Rspec
|
2
|
-
|
3
|
-
|
2
|
+
module Generators
|
3
|
+
class DecoratorGenerator < ::Rails::Generators::NamedBase
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
def create_spec_file
|
7
|
+
template 'decorator_spec.rb', File.join('spec/decorators', class_path, "#{singular_name}_decorator_spec.rb")
|
8
|
+
end
|
7
9
|
end
|
8
10
|
end
|
9
11
|
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
module TestUnit
|
2
|
-
|
3
|
-
|
2
|
+
module Generators
|
3
|
+
class DecoratorGenerator < ::Rails::Generators::NamedBase
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
5
|
+
check_class_collision suffix: "DecoratorTest"
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
+
def create_test_file
|
8
|
+
template 'decorator_test.rb', File.join('test/decorators', class_path, "#{singular_name}_decorator_test.rb")
|
9
|
+
end
|
7
10
|
end
|
8
11
|
end
|
9
12
|
end
|
@@ -73,6 +73,16 @@ module Draper
|
|
73
73
|
expect(Product).to receive(:decorator_class).and_return(:some_decorator)
|
74
74
|
expect(product.decorator_class).to be :some_decorator
|
75
75
|
end
|
76
|
+
|
77
|
+
it "specifies the class that #decorator_class was first called on (superclass)" do
|
78
|
+
person = Person.new
|
79
|
+
expect { person.decorator_class }.to raise_error(Draper::UninferrableDecoratorError, 'Could not infer a decorator for Person.')
|
80
|
+
end
|
81
|
+
|
82
|
+
it "specifies the class that #decorator_class was first called on (subclass)" do
|
83
|
+
child = Child.new
|
84
|
+
expect { child.decorator_class }.to raise_error(Draper::UninferrableDecoratorError, 'Could not infer a decorator for Child.')
|
85
|
+
end
|
76
86
|
end
|
77
87
|
|
78
88
|
describe "#==" do
|
@@ -205,10 +215,22 @@ module Draper
|
|
205
215
|
|
206
216
|
context "when an unrelated NameError is thrown" do
|
207
217
|
it "re-raises that error" do
|
208
|
-
|
218
|
+
# Not related to safe_constantize behavior, we just want to raise a NameError inside the function
|
219
|
+
allow_any_instance_of(String).to receive(:safe_constantize) { Draper::Base }
|
209
220
|
expect{Product.decorator_class}.to raise_error NameError, /Draper::Base/
|
210
221
|
end
|
211
222
|
end
|
223
|
+
|
224
|
+
context "when an anonymous class is given" do
|
225
|
+
it "infers the decorator from a superclass" do
|
226
|
+
anonymous_class = Class.new(Product) do
|
227
|
+
def self.name
|
228
|
+
to_s
|
229
|
+
end
|
230
|
+
end
|
231
|
+
expect(anonymous_class.decorator_class).to be ProductDecorator
|
232
|
+
end
|
233
|
+
end
|
212
234
|
end
|
213
235
|
|
214
236
|
end
|
@@ -202,7 +202,8 @@ module Draper
|
|
202
202
|
|
203
203
|
context "when an unrelated NameError is thrown" do
|
204
204
|
it "re-raises that error" do
|
205
|
-
|
205
|
+
# Not related to safe_constantize behavior, we just want to raise a NameError inside the function
|
206
|
+
allow_any_instance_of(String).to receive(:safe_constantize) { SomethingThatDoesntExist }
|
206
207
|
expect{ProductDecorator.object_class}.to raise_error NameError, /SomethingThatDoesntExist/
|
207
208
|
end
|
208
209
|
end
|
@@ -225,7 +226,7 @@ module Draper
|
|
225
226
|
|
226
227
|
describe '.collection_decorator_class' do
|
227
228
|
it 'defaults to CollectionDecorator' do
|
228
|
-
allow_any_instance_of(String).to receive(:
|
229
|
+
allow_any_instance_of(String).to receive(:safe_constantize) { nil }
|
229
230
|
expect(ProductDecorator.collection_decorator_class).to be Draper::CollectionDecorator
|
230
231
|
end
|
231
232
|
|
@@ -38,9 +38,6 @@ module Dummy
|
|
38
38
|
# Configure the default encoding used in templates for Ruby 1.9.
|
39
39
|
config.encoding = "utf-8"
|
40
40
|
|
41
|
-
# Configure sensitive parameters which will be filtered from the log file.
|
42
|
-
config.filter_parameters += [:password]
|
43
|
-
|
44
41
|
# Enable escaping HTML in JSON.
|
45
42
|
config.active_support.escape_html_entities_in_json = true
|
46
43
|
|
@@ -1,6 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'shared_examples/decoratable'
|
3
3
|
|
4
|
-
describe Post do
|
5
|
-
it_behaves_like
|
4
|
+
RSpec.describe Post do
|
5
|
+
it_behaves_like 'a decoratable model'
|
6
|
+
|
7
|
+
it { should be_a ApplicationRecord }
|
8
|
+
|
9
|
+
describe '#to_global_id' do
|
10
|
+
let(:post) { Post.create }
|
11
|
+
subject { post.to_global_id }
|
12
|
+
|
13
|
+
it { is_expected.to eq post.decorate.to_global_id }
|
14
|
+
end
|
6
15
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -16,6 +16,8 @@ class Model; include Draper::Decoratable; end
|
|
16
16
|
class Product < Model; end
|
17
17
|
class SpecialProduct < Product; end
|
18
18
|
class Other < Model; end
|
19
|
+
class Person < Model; end
|
20
|
+
class Child < Person; end
|
19
21
|
class ProductDecorator < Draper::Decorator; end
|
20
22
|
class ProductsDecorator < Draper::CollectionDecorator; end
|
21
23
|
|
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: 3.0.
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Casimir
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-10-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -207,6 +207,7 @@ files:
|
|
207
207
|
- lib/draper/automatic_delegation.rb
|
208
208
|
- lib/draper/collection_decorator.rb
|
209
209
|
- lib/draper/compatibility/api_only.rb
|
210
|
+
- lib/draper/compatibility/global_id.rb
|
210
211
|
- lib/draper/configuration.rb
|
211
212
|
- lib/draper/decoratable.rb
|
212
213
|
- lib/draper/decoratable/equality.rb
|
@@ -267,9 +268,11 @@ files:
|
|
267
268
|
- spec/dummy/app/decorators/mongoid_post_decorator.rb
|
268
269
|
- spec/dummy/app/decorators/post_decorator.rb
|
269
270
|
- spec/dummy/app/helpers/application_helper.rb
|
271
|
+
- spec/dummy/app/jobs/publish_post_job.rb
|
270
272
|
- spec/dummy/app/mailers/application_mailer.rb
|
271
273
|
- spec/dummy/app/mailers/post_mailer.rb
|
272
274
|
- spec/dummy/app/models/admin.rb
|
275
|
+
- spec/dummy/app/models/application_record.rb
|
273
276
|
- spec/dummy/app/models/mongoid_post.rb
|
274
277
|
- spec/dummy/app/models/post.rb
|
275
278
|
- spec/dummy/app/models/user.rb
|
@@ -288,6 +291,7 @@ files:
|
|
288
291
|
- spec/dummy/config/environments/test.rb
|
289
292
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
290
293
|
- spec/dummy/config/initializers/draper.rb
|
294
|
+
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
291
295
|
- spec/dummy/config/initializers/inflections.rb
|
292
296
|
- spec/dummy/config/initializers/mime_types.rb
|
293
297
|
- spec/dummy/config/initializers/secret_token.rb
|
@@ -312,7 +316,9 @@ files:
|
|
312
316
|
- spec/dummy/spec/decorators/post_decorator_spec.rb
|
313
317
|
- spec/dummy/spec/decorators/spec_type_spec.rb
|
314
318
|
- spec/dummy/spec/decorators/view_context_spec.rb
|
319
|
+
- spec/dummy/spec/jobs/publish_post_job_spec.rb
|
315
320
|
- spec/dummy/spec/mailers/post_mailer_spec.rb
|
321
|
+
- spec/dummy/spec/models/application_spec.rb
|
316
322
|
- spec/dummy/spec/models/mongoid_post_spec.rb
|
317
323
|
- spec/dummy/spec/models/post_spec.rb
|
318
324
|
- spec/dummy/spec/shared_examples/decoratable.rb
|
@@ -389,9 +395,11 @@ test_files:
|
|
389
395
|
- spec/dummy/app/decorators/mongoid_post_decorator.rb
|
390
396
|
- spec/dummy/app/decorators/post_decorator.rb
|
391
397
|
- spec/dummy/app/helpers/application_helper.rb
|
398
|
+
- spec/dummy/app/jobs/publish_post_job.rb
|
392
399
|
- spec/dummy/app/mailers/application_mailer.rb
|
393
400
|
- spec/dummy/app/mailers/post_mailer.rb
|
394
401
|
- spec/dummy/app/models/admin.rb
|
402
|
+
- spec/dummy/app/models/application_record.rb
|
395
403
|
- spec/dummy/app/models/mongoid_post.rb
|
396
404
|
- spec/dummy/app/models/post.rb
|
397
405
|
- spec/dummy/app/models/user.rb
|
@@ -410,6 +418,7 @@ test_files:
|
|
410
418
|
- spec/dummy/config/environments/test.rb
|
411
419
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
412
420
|
- spec/dummy/config/initializers/draper.rb
|
421
|
+
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
413
422
|
- spec/dummy/config/initializers/inflections.rb
|
414
423
|
- spec/dummy/config/initializers/mime_types.rb
|
415
424
|
- spec/dummy/config/initializers/secret_token.rb
|
@@ -434,7 +443,9 @@ test_files:
|
|
434
443
|
- spec/dummy/spec/decorators/post_decorator_spec.rb
|
435
444
|
- spec/dummy/spec/decorators/spec_type_spec.rb
|
436
445
|
- spec/dummy/spec/decorators/view_context_spec.rb
|
446
|
+
- spec/dummy/spec/jobs/publish_post_job_spec.rb
|
437
447
|
- spec/dummy/spec/mailers/post_mailer_spec.rb
|
448
|
+
- spec/dummy/spec/models/application_spec.rb
|
438
449
|
- spec/dummy/spec/models/mongoid_post_spec.rb
|
439
450
|
- spec/dummy/spec/models/post_spec.rb
|
440
451
|
- spec/dummy/spec/shared_examples/decoratable.rb
|