pragma-decorator 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bbec18405551712b35736d4c0ce74e0981ed356e
4
- data.tar.gz: bacafc3eca685e41332be8991ff1709d36d5cddc
2
+ SHA256:
3
+ metadata.gz: '0845e95dd2b1793d4db9ddc6280f62fb9420a385416779de9d0de56573a4ba18'
4
+ data.tar.gz: 85d1bf273b7748ab953eea1861e3e9935dc548b3d90a6815ffd25fd26c255dbb
5
5
  SHA512:
6
- metadata.gz: 9e08aabbc192fd4c81f638ae98d92b71b23663a2aad72db873f148edeb63211c5878e6072d7dbb377e0bdf72bbe7851ecd9262d02772b159c7aff8e1f4bebe52
7
- data.tar.gz: b0f12d8e1196b6205de676aa7bffc270d20342e0b3b7ec8a517cf8693e53f67970a449e37659f2c291f417111d5e98554f6717bd71d70f5e9a34ffa1593338c0
6
+ metadata.gz: 596e58d11fc5b7e309ef09a443002d7bd79acb5aada4f7a09eb85b449f357a55995600d0f93ae003d0ef32ef8373c6038c9d187b9a074715c90a91dfa9dc2403
7
+ data.tar.gz: f36e57ae761386a60c87245182f9f186803300ec77af42c0a7893568dba99967e85258c6cdfa39bfb8d71f7de21330d7d677dec69edfecae6117bd7036a913b7
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  /spec/examples.txt
10
+ .ruby-version
data/CHANGELOG.md CHANGED
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.2.0]
11
+
12
+ ### Added
13
+
14
+ - Added support for custom pagination adapters
15
+ - Implemented STI support in `Collection`
16
+
17
+ ### Changed
18
+
19
+ - Renamed `Pagination#adapter` to `#pagination_adapter`
20
+ - `Type` now replaces `::` with `/`
21
+
22
+ ### Fixed
23
+
24
+ - Fixed AR association adapter not working with custom scopes
25
+ - Fixed AR association adapter not working with `has_one`
26
+ - Fixed associations inheritance
27
+ - Fixed association expansion for non-AR associations defined on AR models
28
+
10
29
  ## [2.1.1]
11
30
 
12
31
  ### Fixed
@@ -38,6 +57,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
38
57
  First Pragma 2 release.
39
58
 
40
59
  [Unreleased]: https://github.com/pragmarb/pragma-decorator/compare/v2.1.1...HEAD
60
+ [2.2.0]: https://github.com/pragmarb/pragma-decorator/compare/v2.1.1...v2.2.0
41
61
  [2.1.1]: https://github.com/pragmarb/pragma-decorator/compare/v2.1.0...v2.1.1
42
62
  [2.1.0]: https://github.com/pragmarb/pragma-decorator/compare/v2.0.0...v2.1.0
43
63
  [2.0.0]: https://github.com/pragmarb/pragma-decorator/compare/v1.2.0...v2.0.0
@@ -61,7 +61,8 @@ module Pragma
61
61
  #
62
62
  # @todo Allow to specify a different PK attribute when +exec_context+ is +decorator+
63
63
  def primary_key
64
- return associated_object&.id if reflection.options[:exec_context] == :decorator
64
+ return associated_object&.id if association_reflection.nil? ||
65
+ reflection.options[:exec_context] == :decorator
65
66
 
66
67
  case reflection.type
67
68
  when :belongs_to
@@ -103,7 +104,7 @@ module Pragma
103
104
 
104
105
  def compute_has_one_fk
105
106
  if model.association(reflection.property).loaded?
106
- return associated_object&.public_send(associated_object.association_primary_key)
107
+ return associated_object&.public_send(association_reflection.association_primary_key)
107
108
  end
108
109
 
109
110
  pluck_association_fk do |scope|
@@ -116,7 +117,7 @@ module Pragma
116
117
  scope = association_reflection.klass.all
117
118
 
118
119
  if association_reflection.scope
119
- scope = association_reflection.instance_eval(&association_reflection.scope)
120
+ scope = scope.instance_eval(&association_reflection.scope)
120
121
  end
121
122
 
122
123
  yield(scope).pluck(association_reflection.association_primary_key).first
@@ -127,6 +128,7 @@ module Pragma
127
128
  end
128
129
 
129
130
  def check_type_consistency
131
+ return unless association_reflection
130
132
  return if association_reflection.macro.to_sym == reflection.type.to_sym
131
133
 
132
134
  fail InconsistentTypeError.new(
@@ -29,7 +29,7 @@ module Pragma
29
29
  #
30
30
  # @return [Hash{Symbol => Reflection}] the associations
31
31
  def associations
32
- @associations ||= {}
32
+ @associations ||= superclass.respond_to?(:associations) ? superclass.associations : {}
33
33
  end
34
34
 
35
35
  # Defines a +belongs_to+ association on this decorator.
@@ -35,7 +35,18 @@ module Pragma
35
35
  klass.extend ClassMethods
36
36
 
37
37
  klass.class_eval do
38
- collection :represented, as: :data, exec_context: :decorator
38
+ collection :data, exec_context: :decorator, getter: (lambda do |options:, **|
39
+ represented_collection = if self.class.instance_decorator.is_a?(Proc)
40
+ represented.map do |item|
41
+ self.class.instance_decorator.call(item).represent(item).to_hash(options)
42
+ end
43
+ elsif self.class.instance_decorator
44
+ self.class.instance_decorator.represent(represented.to_a).to_hash(options)
45
+ else
46
+ represented
47
+ end
48
+ represented_collection
49
+ end)
39
50
  end
40
51
  end
41
52
 
@@ -49,13 +60,16 @@ module Pragma
49
60
  end
50
61
 
51
62
  module ClassMethods # :nodoc:
63
+ # @!attribute [r]
64
+ # @return [Class\Proc] the instance decorator to use
65
+ attr_reader :instance_decorator
66
+
52
67
  # Defines the decorator to use for each resource in the collection.
53
68
  #
54
- # @param decorator [Class] a decorator class
55
- #
56
- # @todo Accept a callable/block or document how to decorate polymorphic collections
69
+ # @param decorator [Class|Proc] a decorator class, or a callable accepting a represented
70
+ # object as argument and returning a decorator class
57
71
  def decorate_with(decorator)
58
- collection :represented, as: :data, exec_context: :decorator, decorator: decorator
72
+ @instance_decorator = decorator
59
73
  end
60
74
  end
61
75
  end
@@ -3,7 +3,7 @@
3
3
  module Pragma
4
4
  module Decorator
5
5
  module Pagination
6
- module Adapter
6
+ module Adapter # :nodoc:
7
7
  # This adapter provides support for retireving pagination information from collections
8
8
  # paginated with {https://github.com/kaminari/kaminari Kaminari}.
9
9
  #
@@ -65,6 +65,8 @@ module Pragma
65
65
  collection.next_page
66
66
  end
67
67
  end
68
+
69
+ adapters << Kaminari
68
70
  end
69
71
  end
70
72
  end
@@ -3,8 +3,8 @@
3
3
  module Pragma
4
4
  module Decorator
5
5
  module Pagination
6
- module Adapter
7
- # This adapter provides support for retireving pagination information from collections
6
+ module Adapter # :nodoc:
7
+ # This adapter provides support for retrieving pagination information from collections
8
8
  # paginated with {https://github.com/mislav/will_paginate will_paginate}.
9
9
  #
10
10
  # @api private
@@ -65,6 +65,8 @@ module Pragma
65
65
  collection.next_page
66
66
  end
67
67
  end
68
+
69
+ adapters << WillPaginate
68
70
  end
69
71
  end
70
72
  end
@@ -8,29 +8,37 @@ module Pragma
8
8
  #
9
9
  # @api private
10
10
  module Adapter
11
- # The list of supported adapters, in order of priority.
12
- SUPPORTED_ADAPTERS = [Kaminari, WillPaginate].freeze
11
+ class << self
12
+ # Loads the adapter for the given collection.
13
+ #
14
+ # This will try {SUPPORTED_ADAPTERS} in order until it finds an adapter that supports the
15
+ # collection. When the adapter is found, it will return a new instance of it.
16
+ #
17
+ # @param collection [Object] the collection to load the adapter for
18
+ #
19
+ # @return [Adapter::Base]
20
+ #
21
+ # @see Adapter::Base.supports?
22
+ #
23
+ # @raise [AdapterError] if no adapter supports the collection
24
+ def load_for(collection)
25
+ adapter_klass = adapters.find do |klass|
26
+ klass.supports?(collection)
27
+ end
13
28
 
14
- # Loads the adapter for the given collection.
15
- #
16
- # This will try {SUPPORTED_ADAPTERS} in order until it finds an adapter that supports the
17
- # collection. When the adapter is found, it will return a new instance of it.
18
- #
19
- # @param collection [Object] the collection to load the adapter for
20
- #
21
- # @return [Adapter::Base]
22
- #
23
- # @see Adapter::Base.supports?
24
- #
25
- # @raise [AdapterError] if no adapter supports the collection
26
- def self.load_for(collection)
27
- adapter_klass = SUPPORTED_ADAPTERS.find do |klass|
28
- klass.supports?(collection)
29
- end
29
+ fail NoAdapterError unless adapter_klass
30
30
 
31
- fail NoAdapterError unless adapter_klass
31
+ adapter_klass.new(collection)
32
+ end
32
33
 
33
- adapter_klass.new(collection)
34
+ # Returns the available pagination adpaters.
35
+ #
36
+ # This can be used to register new adapters: just append your class to the collection.
37
+ #
38
+ # @return [Array] an array of pagination adapters
39
+ def adapters
40
+ @adapters ||= []
41
+ end
34
42
  end
35
43
 
36
44
  # This error is raised when no adapter can be found for a collection.
@@ -37,7 +37,7 @@ module Pragma
37
37
  #
38
38
  # @see Adapter::Base#current_page
39
39
  def current_page
40
- adapter.current_page
40
+ pagination_adapter.current_page
41
41
  end
42
42
 
43
43
  # Returns the next page of the collection.
@@ -46,7 +46,7 @@ module Pragma
46
46
  #
47
47
  # @see Adapter::Base#next_page
48
48
  def next_page
49
- adapter.next_page
49
+ pagination_adapter.next_page
50
50
  end
51
51
 
52
52
  # Returns the number of items per page in the collection.
@@ -55,7 +55,7 @@ module Pragma
55
55
  #
56
56
  # @see Adapter::Base#per_page
57
57
  def per_page
58
- adapter.per_page
58
+ pagination_adapter.per_page
59
59
  end
60
60
 
61
61
  # Returns the previous page of the collection.
@@ -64,7 +64,7 @@ module Pragma
64
64
  #
65
65
  # @see Adapter::Base#previous_page
66
66
  def previous_page
67
- adapter.previous_page
67
+ pagination_adapter.previous_page
68
68
  end
69
69
 
70
70
  # Returns the total number of items in the collection.
@@ -73,7 +73,7 @@ module Pragma
73
73
  #
74
74
  # @see Adapter::Base#total_entries
75
75
  def total_entries
76
- adapter.total_entries
76
+ pagination_adapter.total_entries
77
77
  end
78
78
 
79
79
  # Returns the total number of pages in the collection.
@@ -82,13 +82,13 @@ module Pragma
82
82
  #
83
83
  # @see Adapter::Base#total_pages
84
84
  def total_pages
85
- adapter.total_pages
85
+ pagination_adapter.total_pages
86
86
  end
87
87
 
88
88
  private
89
89
 
90
- def adapter
91
- @adapter ||= Pagination::Adapter.load_for(represented)
90
+ def pagination_adapter
91
+ @pagination_adapter ||= Pagination::Adapter.load_for(represented)
92
92
  end
93
93
  end
94
94
 
@@ -56,6 +56,7 @@ module Pragma
56
56
  klass
57
57
  .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
58
58
  .gsub(/([a-z\d])([A-Z])/, '\1_\2')
59
+ .gsub('::', '/')
59
60
  .downcase
60
61
  end
61
62
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Pragma
4
4
  module Decorator
5
- VERSION = '2.1.1'
5
+ VERSION = '2.2.0'
6
6
  end
7
7
  end
@@ -16,10 +16,10 @@ require 'pragma/decorator/timestamp'
16
16
  require 'pragma/decorator/type'
17
17
  require 'pragma/decorator/collection'
18
18
  require 'pragma/decorator/pagination'
19
+ require 'pragma/decorator/pagination/adapter'
19
20
  require 'pragma/decorator/pagination/adapter/base'
20
21
  require 'pragma/decorator/pagination/adapter/kaminari'
21
22
  require 'pragma/decorator/pagination/adapter/will_paginate'
22
- require 'pragma/decorator/pagination/adapter'
23
23
 
24
24
  module Pragma
25
25
  # Represent your API resources in JSON with minimum hassle.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pragma-decorator
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.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: 2018-01-15 00:00:00.000000000 Z
11
+ date: 2018-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: roar
@@ -180,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
180
  version: '0'
181
181
  requirements: []
182
182
  rubyforge_project:
183
- rubygems_version: 2.6.13
183
+ rubygems_version: 2.7.5
184
184
  signing_key:
185
185
  specification_version: 4
186
186
  summary: Convert your API resources into JSON with minimum hassle.