ams_lazy_relationships 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d299c4294fa21bc85d59919b153f88de9f78a4ed9a2f2d7f87cf98cdc8093706
4
- data.tar.gz: 9a66c679744b7e8128ce492209f3743e397cb0f3d1eec93097667c7c0e142863
3
+ metadata.gz: cf2c7b4fd222fcde15c3f1accd9784c421455d988bf4ec6bf2c76b4029cf2718
4
+ data.tar.gz: 306b361e74fa64697a046c9b67d0b5dd1bdbfc930c2a77df4e443fc65bb2de6a
5
5
  SHA512:
6
- metadata.gz: 2683f61c4107464423359aecb53193f6e5d9de727812916282e7eb6c3848541fc3212d4be773d288044582ef29ba7832d2558fd80e60fed0af2ef833dc2bb858
7
- data.tar.gz: c9c777b5d1d56ad21289db010206cc20aa61225eacd9041a29f68745942e72696bee19acfef86eca4d08dba34152ff3e6ba3a1d0833296a0759c91e6203583f2
6
+ metadata.gz: 36ed2e0404138db614928261d8dfd771b185fa9fd62dc6e091e5ee037b05bf3fec3d6a0e20fdd254ac100ffbbcc2ee175c9e16296d0a2120fa47968f2c15ef5d
7
+ data.tar.gz: 0eac844f0f061f4e9769cea6835de6eebc75415d3fefc5aff82c2b838bef9c22609188d24ba8bd2b33851e0ce2c0fc8e19fef4ebc00f92e217e980394529fd3d
@@ -6,8 +6,11 @@ env:
6
6
  language: ruby
7
7
  gemfile:
8
8
  - gemfiles/ams_0.10.0.rc4.gemfile
9
+ - gemfiles/ams_0.10.0.gemfile
9
10
  - gemfiles/ams_0.10.2.gemfile
11
+ - gemfiles/ams_0.10.3.gemfile
10
12
  - gemfiles/ams_0.10.8.gemfile
13
+ - gemfiles/ams_0.10.10.gemfile
11
14
  cache: bundler
12
15
  rvm:
13
16
  - 2.5.3
data/Appraisals CHANGED
@@ -2,10 +2,22 @@ appraise "ams-0.10.0.rc4" do
2
2
  gem "active_model_serializers", "0.10.0.rc4"
3
3
  end
4
4
 
5
+ appraise "ams-0.10.0" do
6
+ gem "active_model_serializers", "0.10.0"
7
+ end
8
+
5
9
  appraise "ams-0.10.2" do
6
10
  gem "active_model_serializers", "0.10.2"
7
11
  end
8
12
 
13
+ appraise "ams-0.10.3" do
14
+ gem "active_model_serializers", "0.10.3"
15
+ end
16
+
9
17
  appraise "ams-0.10.8" do
10
18
  gem "active_model_serializers", "0.10.8"
11
19
  end
20
+
21
+ appraise "ams-0.10.10" do
22
+ gem "active_model_serializers", "0.10.10"
23
+ end
@@ -1,5 +1,17 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.3.0](https://github.com/Bajena/ams_lazy_relationships/tree/v0.3.0) (2020-01-16)
4
+ [Full Changelog](https://github.com/Bajena/ams_lazy_relationships/compare/v0.2.0...v0.3.0)
5
+
6
+ **Merged pull requests:**
7
+
8
+ - Fix association duplicates after accepts\_nested\_attributes\_for assignation [\#50](https://github.com/Bajena/ams_lazy_relationships/pull/50) ([stokarenko](https://github.com/stokarenko))
9
+ - Skip active\_support as redundant dependency [\#49](https://github.com/Bajena/ams_lazy_relationships/pull/49) ([stokarenko](https://github.com/stokarenko))
10
+ - Test against AMS v0.10.0.rc4 [\#48](https://github.com/Bajena/ams_lazy_relationships/pull/48) ([stokarenko](https://github.com/stokarenko))
11
+ - Skip redundant queries when include\_data is disabled [\#47](https://github.com/Bajena/ams_lazy_relationships/pull/47) ([stokarenko](https://github.com/stokarenko))
12
+ - Adjust tested ams version [\#46](https://github.com/Bajena/ams_lazy_relationships/pull/46) ([stokarenko](https://github.com/stokarenko))
13
+ - Fix documentation for blocked relationships [\#45](https://github.com/Bajena/ams_lazy_relationships/pull/45) ([stokarenko](https://github.com/stokarenko))
14
+
3
15
  ## [v0.2.0](https://github.com/Bajena/ams_lazy_relationships/tree/v0.2.0) (2020-01-11)
4
16
  [Full Changelog](https://github.com/Bajena/ams_lazy_relationships/compare/v0.1.5...v0.2.0)
5
17
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ams_lazy_relationships (0.2.0)
4
+ ams_lazy_relationships (0.3.0)
5
5
  active_model_serializers
6
6
  batch-loader (~> 1)
7
7
 
data/README.md CHANGED
@@ -63,8 +63,10 @@ class UserSerializer < BaseSerializer
63
63
 
64
64
  # The previous one is a shorthand for the following lines:
65
65
  lazy_relationship :blog_posts, loader: AmsLazyRelationships::Loaders::Association.new("User", :blog_posts)
66
- has_many :blog_posts, serializer: BlogPostSerializer do
67
- lazy_blog_posts
66
+ has_many :blog_posts, serializer: BlogPostSerializer do |serializer|
67
+ # non-proc custom finder will work as well, but it can produce redundant sql
68
+ # queries, please see [Example 2: Modifying the relationship before rendering](#example-2-modifying-the-relationship-before-rendering)
69
+ -> { serializer.lazy_blog_posts }
68
70
  end
69
71
 
70
72
  lazy_has_one :poro_model, loader: AmsLazyRelationships::Loaders::Direct.new(:poro_model) { |object| PoroModel.new(object) }
@@ -116,10 +118,43 @@ end
116
118
  #### Example 2: Modifying the relationship before rendering
117
119
  Sometimes it may happen that you need to process the relationship before rendering, e.g. decorate the records. In this case the gem provides a special method (in our case `lazy_comments`) for each defined relationship. Check out the example - we'll decorate every comment before serializing:
118
120
 
121
+ ```ruby
122
+ class BlogPostSerializer < BaseSerializer
123
+ lazy_has_many :comments do |serializer|
124
+ -> { serializer.lazy_comments.map(&:decorate) }
125
+ end
126
+ end
127
+ ```
128
+
129
+ Despite the fact that non-block custom finder such as
130
+
131
+ ```ruby
132
+ class BlogPostSerializer < BaseSerializer
133
+ lazy_has_many :comments do |serializer|
134
+ serializer.lazy_comments.map(&:decorate)
135
+ end
136
+ end
137
+ ```
138
+
139
+ will work still, it's better to implement it in a form of lambda, in order to avoid redundant SQL queries when `include_data` AMS setting appears to be `false`:
140
+
141
+ ```ruby
142
+ class BlogPostSerializer < BaseSerializer
143
+ lazy_has_many :comments do |serializer|
144
+ include_data :if_sideloaded
145
+ -> { serializer.lazy_comments.map(&:decorate) }
146
+ end
147
+ end
148
+ ```
149
+
150
+ Feel free to skip custom lazy finder for association if your goal is just to define `include_data` setting and/or to specify some links and metas:
151
+
119
152
  ```ruby
120
153
  class BlogPostSerializer < BaseSerializer
121
154
  lazy_has_many :comments do
122
- lazy_comments.map(&:decorate)
155
+ include_data :if_sideloaded
156
+ link :self, 'a link'
157
+ meta name: 'Dan Brown'
123
158
  end
124
159
  end
125
160
  ```
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "active_model_serializers", "0.10.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "active_model_serializers", "0.10.10"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "active_model_serializers", "0.10.3"
6
+
7
+ gemspec path: "../"
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "batch-loader"
4
+ require "active_model_serializers"
4
5
 
5
6
  require "ams_lazy_relationships/version"
7
+ require "ams_lazy_relationships/extensions"
6
8
  require "ams_lazy_relationships/loaders"
7
9
  require "ams_lazy_relationships/core"
8
10
 
@@ -19,7 +19,7 @@ module AmsLazyRelationships::Core
19
19
  define_singleton_method(
20
20
  "lazy_#{relationship_type}"
21
21
  ) do |relationship_name, options = {}, &block|
22
- send(:define_lazy_association, relationship_type, relationship_name, options, block)
22
+ define_lazy_association(relationship_type, relationship_name, options, block)
23
23
  end
24
24
  end
25
25
  end
@@ -29,11 +29,20 @@ module AmsLazyRelationships::Core
29
29
 
30
30
  real_relationship_options = options.except(*lazy_relationship_option_keys)
31
31
 
32
- block ||= lambda do |serializer|
33
- serializer.public_send("lazy_#{name}")
34
- end
32
+ public_send(type, name.to_sym, real_relationship_options) do |serializer|
33
+ block_value = instance_exec(serializer, &block) if block
35
34
 
36
- public_send(type, name.to_sym, real_relationship_options, &block)
35
+ if block && block_value != :nil
36
+ # respect the custom finder for lazy association
37
+ # @see https://github.com/rails-api/active_model_serializers/blob/v0.10.10/lib/active_model/serializer/reflection.rb#L165-L168
38
+ block_value
39
+ else
40
+ # provide default lazy association finder in a form of lambda,
41
+ # in order to play nice with possible `include_data` setting.
42
+ # @see lib/ams_lazy_relationships/extensions/reflection.rb
43
+ serializer.method("lazy_#{name}")
44
+ end
45
+ end
37
46
 
38
47
  lazy_relationship(name, options.slice(*lazy_relationship_option_keys))
39
48
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ams_lazy_relationships/extensions/reflection"
4
+
5
+ module AmsLazyRelationships
6
+ module Extensions
7
+ end
8
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # There is a general problem inside AMS related to custom association finder
4
+ # combined with `include_data` setting:
5
+ #
6
+ # class BlogPostSerializer < BaseSerializer
7
+ # belongs_to :category do
8
+ # include_data :if_sideloaded
9
+ # object.categories.last
10
+ # end
11
+ # end
12
+ #
13
+ # The problem is that `belongs_to` block will be fully evaluated each time for
14
+ # each object, and only after that AMS is able to take into account
15
+ # `include_data` mode -
16
+ # https://github.com/rails-api/active_model_serializers/blob/v0.10.10/lib/active_model/serializer/reflection.rb#L162-L163
17
+ #
18
+ # def value(serializer, include_slice)
19
+ # # ...
20
+ # block_value = instance_exec(serializer, &block) if block
21
+ # return unless include_data?(include_slice)
22
+ # # ...
23
+ # end
24
+ #
25
+ # That causing redundant (and so huge potentially!) SQL queries and AR objects
26
+ # allocation when `include_data` appears to be `false` but `belongs_to` block
27
+ # defines instant (not a kind of AR::Relation) custom association finder.
28
+ #
29
+ # Described problem is a very specific use case for pure AMS applications.
30
+ # The bad news is that `ams_lazy_relationships` always utilizes the
31
+ # association block -
32
+ # https://github.com/Bajena/ams_lazy_relationships/blob/v0.2.0/lib/ams_lazy_relationships/core/relationship_wrapper_methods.rb#L32-L36
33
+ #
34
+ # def define_lazy_association(type, name, options, block)
35
+ # #...
36
+ # block ||= lambda do |serializer|
37
+ # serializer.public_send("lazy_#{name}")
38
+ # end
39
+ #
40
+ # public_send(type, name.to_sym, real_relationship_options, &block)
41
+ # #...
42
+ # end
43
+ #
44
+ # This way we break `include_data` optimizations for the host application.
45
+ #
46
+ # In order to overcome that we are forced to monkey-patch
47
+ # `AmsLazyRelationships::Extensions::Reflection#value` method and make it to be
48
+ # ready for Proc returned by association block. This way we will use a kind of
49
+ #
50
+ # block ||= lambda do |serializer|
51
+ # -> { serializer.public_send("lazy_#{name}") }
52
+ # end
53
+ #
54
+ # as association block, then AMS will evaluate it, get the value of `include_data`
55
+ # setting, make a decision do we need to continue with that association, if so -
56
+ # will finally evaluate the proc with lazy relationship inside it.
57
+
58
+ module AmsLazyRelationships
59
+ module Extensions
60
+ module Reflection
61
+ def value(*)
62
+ case (block_value = super)
63
+ when Proc, Method then block_value.call
64
+ else block_value
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ ::ActiveModel::Serializer::Reflection.prepend AmsLazyRelationships::Extensions::Reflection
@@ -45,9 +45,19 @@ module AmsLazyRelationships
45
45
  # in a decorator and non-wrapped). In this case Associations::Preloader
46
46
  # stores duplicated records in has_many relationships for some reason.
47
47
  # Calling uniq(&:id) solves the problem.
48
- records.uniq(&:id).reject do |r|
49
- r.association(association_name).loaded?
50
- end
48
+ #
49
+ # One more case when duplicated records appear in has_many relationships
50
+ # is the recent assignation to `accept_nested_attributes_for` setter.
51
+ # ActiveRecord will not mark the association as `loaded` but in same
52
+ # time will keep internal representation of the nested records created
53
+ # by `accept_nested_attributes_for`. Then Associations::Preloader is
54
+ # going to merge internal state of associated records with the same
55
+ # records recently stored in DB. `r.association(association_name).reset`
56
+ # effectively fixes that.
57
+ records.
58
+ uniq(&:id).
59
+ reject { |r| r.association(association_name).loaded? }.
60
+ each { |r| r.association(association_name).reset }
51
61
  end
52
62
  end
53
63
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AmsLazyRelationships
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ams_lazy_relationships
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Bajena
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-11 00:00:00.000000000 Z
11
+ date: 2020-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_model_serializers
@@ -300,8 +300,11 @@ files:
300
300
  - bin/console
301
301
  - bin/setup
302
302
  - gemfiles/.bundle/config
303
+ - gemfiles/ams_0.10.0.gemfile
303
304
  - gemfiles/ams_0.10.0.rc4.gemfile
305
+ - gemfiles/ams_0.10.10.gemfile
304
306
  - gemfiles/ams_0.10.2.gemfile
307
+ - gemfiles/ams_0.10.3.gemfile
305
308
  - gemfiles/ams_0.10.8.gemfile
306
309
  - lib/ams_lazy_relationships.rb
307
310
  - lib/ams_lazy_relationships/core.rb
@@ -310,6 +313,8 @@ files:
310
313
  - lib/ams_lazy_relationships/core/lazy_relationship_meta.rb
311
314
  - lib/ams_lazy_relationships/core/lazy_relationship_method.rb
312
315
  - lib/ams_lazy_relationships/core/relationship_wrapper_methods.rb
316
+ - lib/ams_lazy_relationships/extensions.rb
317
+ - lib/ams_lazy_relationships/extensions/reflection.rb
313
318
  - lib/ams_lazy_relationships/loaders.rb
314
319
  - lib/ams_lazy_relationships/loaders/association.rb
315
320
  - lib/ams_lazy_relationships/loaders/base.rb