pragma-decorator 1.1.0 → 1.2.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -0
- data/lib/pragma/decorator/association/binding.rb +71 -4
- data/lib/pragma/decorator/association/inconsistent_type_error.rb +27 -0
- data/lib/pragma/decorator/association/reflection.rb +3 -2
- data/lib/pragma/decorator/association/unexpandable_error.rb +1 -0
- data/lib/pragma/decorator/association.rb +4 -1
- data/lib/pragma/decorator/base.rb +1 -0
- data/lib/pragma/decorator/timestamp.rb +1 -0
- data/lib/pragma/decorator/type.rb +1 -0
- data/lib/pragma/decorator/version.rb +2 -1
- data/lib/pragma/decorator.rb +2 -0
- data/pragma-decorator.gemspec +5 -3
- metadata +15 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8cbfb161f363349668460111a7fb2f5936b400a
|
4
|
+
data.tar.gz: 1e49a4456a7d4aaf2a01d217f3fb52538e49fa86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff52579a206fea38b5333c74b84589a579c5b1d0886f633848635fc61a28f6f178176ac609c7a0a53bff1683e173b6652a4628d54c767a3a86be00abbb763f37
|
7
|
+
data.tar.gz: 666eb32eb1ba858e3659ee403af8a40432ef623292f2a7e3ff0fc53ee2c9a023f0256f3ee30043d33c3d346c971c384751a798b124656adf27ed422e10e41815
|
data/.rubocop.yml
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Pragma
|
3
4
|
module Decorator
|
4
5
|
module Association
|
@@ -20,6 +21,8 @@ module Pragma
|
|
20
21
|
def initialize(reflection:, decorator:)
|
21
22
|
@reflection = reflection
|
22
23
|
@decorator = decorator
|
24
|
+
|
25
|
+
check_type_consistency
|
23
26
|
end
|
24
27
|
|
25
28
|
# Returns the associated object.
|
@@ -28,18 +31,52 @@ module Pragma
|
|
28
31
|
def associated_object
|
29
32
|
case reflection.options[:exec_context]
|
30
33
|
when :decorated
|
31
|
-
|
34
|
+
model.public_send(reflection.property)
|
32
35
|
when :decorator
|
33
|
-
decorator.
|
36
|
+
decorator.public_send(reflection.property)
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
40
|
+
# Returns whether the association belongs to the model.
|
41
|
+
#
|
42
|
+
# @return [Boolean]
|
43
|
+
def model_context?
|
44
|
+
reflection.options[:exec_context].to_sym == :decorated
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns whether the association belongs to the decorator.
|
48
|
+
#
|
49
|
+
# @return [Boolean]
|
50
|
+
def decorator_context?
|
51
|
+
reflection.options[:exec_context].to_sym == :decorator
|
52
|
+
end
|
53
|
+
|
37
54
|
# Returns the unexpanded value for the associated object (i.e. its +id+ property).
|
38
55
|
#
|
39
56
|
# @return [String]
|
40
57
|
def unexpanded_value
|
41
|
-
|
42
|
-
|
58
|
+
if decorator_context? || model_reflection.nil?
|
59
|
+
return associated_object&.public_send(associated_object.class.primary_key)
|
60
|
+
end
|
61
|
+
|
62
|
+
case reflection.type
|
63
|
+
when :belongs_to
|
64
|
+
model.public_send(model_reflection.foreign_key)
|
65
|
+
when :has_one
|
66
|
+
if model.association(reflection.property).loaded?
|
67
|
+
return associated_object&.public_send(associated_object.class.primary_key)
|
68
|
+
end
|
69
|
+
|
70
|
+
pk = model.public_send(model_reflection.active_record_primary_key)
|
71
|
+
|
72
|
+
model_reflection
|
73
|
+
.klass
|
74
|
+
.where(model_reflection.foreign_key => pk)
|
75
|
+
.pluck(model_reflection.klass.primary_key)
|
76
|
+
.first
|
77
|
+
else
|
78
|
+
associated_object&.public_send(associated_object.class.primary_key)
|
79
|
+
end
|
43
80
|
end
|
44
81
|
|
45
82
|
# Returns the expanded value for the associated object.
|
@@ -116,6 +153,36 @@ module Pragma
|
|
116
153
|
reflection.options[:decorator]
|
117
154
|
end
|
118
155
|
end
|
156
|
+
|
157
|
+
def model
|
158
|
+
decorator.decorated
|
159
|
+
end
|
160
|
+
|
161
|
+
def model_reflection
|
162
|
+
# rubocop:disable Metrics/LineLength
|
163
|
+
@model_reflection ||= if Object.const_defined?('ActiveRecord') && model.is_a?(ActiveRecord::Base)
|
164
|
+
model.class.reflect_on_association(reflection.property)
|
165
|
+
end
|
166
|
+
# rubocop:enable Metrics/LineLength
|
167
|
+
end
|
168
|
+
|
169
|
+
def model_association_type
|
170
|
+
return unless model_reflection
|
171
|
+
|
172
|
+
if Object.const_defined?('ActiveRecord') && model.is_a?(ActiveRecord::Base)
|
173
|
+
model_reflection.macro
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def check_type_consistency
|
178
|
+
return if !model_association_type || model_association_type == reflection.type
|
179
|
+
|
180
|
+
fail InconsistentTypeError.new(
|
181
|
+
decorator: decorator,
|
182
|
+
reflection: reflection,
|
183
|
+
model_type: model_association_type
|
184
|
+
)
|
185
|
+
end
|
119
186
|
end
|
120
187
|
end
|
121
188
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pragma
|
4
|
+
module Decorator
|
5
|
+
module Association
|
6
|
+
# This error is raised when an association's type is different from its type as reported by
|
7
|
+
# the model's reflection.
|
8
|
+
#
|
9
|
+
# @author Alessandro Desantis
|
10
|
+
class InconsistentTypeError < StandardError
|
11
|
+
# Initializes the error.
|
12
|
+
#
|
13
|
+
# @param decorator [Base] the decorator where the association is defined
|
14
|
+
# @param reflection [Reflection] the reflection of the inconsistent association
|
15
|
+
# @param model_type [Symbol|String] the real type of the association
|
16
|
+
def initialize(decorator:, reflection:, model_type:)
|
17
|
+
message = <<~MSG.tr("\n", ' ')
|
18
|
+
#{decorator.class}: Association #{reflection.property} is defined as #{model_type} on
|
19
|
+
the model, but as #{reflection.type} in the decorator.
|
20
|
+
MSG
|
21
|
+
|
22
|
+
super message
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Pragma
|
3
4
|
module Decorator
|
4
5
|
module Association
|
@@ -50,14 +51,14 @@ module Pragma
|
|
50
51
|
@options = {
|
51
52
|
expandable: false,
|
52
53
|
render_nil: false,
|
53
|
-
exec_context: :decorated
|
54
|
+
exec_context: :decorated,
|
54
55
|
}.merge(options).tap do |opts|
|
55
56
|
opts[:exec_context] = opts[:exec_context].to_sym
|
56
57
|
end
|
57
58
|
end
|
58
59
|
|
59
60
|
def validate_options
|
60
|
-
return if [
|
61
|
+
return if %i[decorator decorated].include?(options[:exec_context])
|
61
62
|
|
62
63
|
fail(
|
63
64
|
ArgumentError,
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Pragma
|
3
4
|
module Decorator
|
4
5
|
# Adds association expansion to decorators.
|
@@ -63,11 +64,13 @@ module Pragma
|
|
63
64
|
end
|
64
65
|
|
65
66
|
def create_association_getter(property)
|
66
|
-
|
67
|
+
code = <<~RUBY
|
67
68
|
def _#{property}_association
|
68
69
|
@association_bindings[:#{property}].render(user_options[:expand])
|
69
70
|
end
|
70
71
|
RUBY
|
72
|
+
|
73
|
+
class_eval code, __FILE__, __LINE__
|
71
74
|
end
|
72
75
|
|
73
76
|
def create_association_property(property_name)
|
data/lib/pragma/decorator.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'roar'
|
3
4
|
|
4
5
|
require 'pragma/decorator/version'
|
@@ -7,6 +8,7 @@ require 'pragma/decorator/association'
|
|
7
8
|
require 'pragma/decorator/association/reflection'
|
8
9
|
require 'pragma/decorator/association/binding'
|
9
10
|
require 'pragma/decorator/association/unexpandable_error'
|
11
|
+
require 'pragma/decorator/association/inconsistent_type_error'
|
10
12
|
require 'pragma/decorator/timestamp'
|
11
13
|
require 'pragma/decorator/type'
|
12
14
|
|
data/pragma-decorator.gemspec
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
lib = File.expand_path('../lib', __FILE__)
|
3
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
6
|
require 'pragma/decorator/version'
|
@@ -20,13 +22,13 @@ Gem::Specification.new do |spec|
|
|
20
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
23
|
spec.require_paths = ['lib']
|
22
24
|
|
23
|
-
spec.add_dependency 'roar', '~> 1.0'
|
24
25
|
spec.add_dependency 'multi_json', '~> 1.12'
|
26
|
+
spec.add_dependency 'roar', '~> 1.0'
|
25
27
|
|
26
28
|
spec.add_development_dependency 'bundler'
|
29
|
+
spec.add_development_dependency 'coveralls'
|
27
30
|
spec.add_development_dependency 'rake'
|
28
31
|
spec.add_development_dependency 'rspec'
|
29
32
|
spec.add_development_dependency 'rubocop'
|
30
33
|
spec.add_development_dependency 'rubocop-rspec'
|
31
|
-
spec.add_development_dependency 'coveralls'
|
32
34
|
end
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pragma-decorator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alessandro Desantis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: multi_json
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.12'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.12'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: roar
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: coveralls
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name: rubocop
|
98
|
+
name: rubocop
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: rubocop-rspec
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
@@ -146,6 +146,7 @@ files:
|
|
146
146
|
- lib/pragma/decorator.rb
|
147
147
|
- lib/pragma/decorator/association.rb
|
148
148
|
- lib/pragma/decorator/association/binding.rb
|
149
|
+
- lib/pragma/decorator/association/inconsistent_type_error.rb
|
149
150
|
- lib/pragma/decorator/association/reflection.rb
|
150
151
|
- lib/pragma/decorator/association/unexpandable_error.rb
|
151
152
|
- lib/pragma/decorator/base.rb
|
@@ -173,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
174
|
version: '0'
|
174
175
|
requirements: []
|
175
176
|
rubyforge_project:
|
176
|
-
rubygems_version: 2.6.
|
177
|
+
rubygems_version: 2.6.13
|
177
178
|
signing_key:
|
178
179
|
specification_version: 4
|
179
180
|
summary: Convert your API resources into JSON with minimum hassle.
|