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 +4 -4
- data/.travis.yml +3 -0
- data/Appraisals +12 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +1 -1
- data/README.md +38 -3
- data/gemfiles/ams_0.10.0.gemfile +7 -0
- data/gemfiles/ams_0.10.10.gemfile +7 -0
- data/gemfiles/ams_0.10.3.gemfile +7 -0
- data/lib/ams_lazy_relationships.rb +2 -0
- data/lib/ams_lazy_relationships/core/relationship_wrapper_methods.rb +14 -5
- data/lib/ams_lazy_relationships/extensions.rb +8 -0
- data/lib/ams_lazy_relationships/extensions/reflection.rb +71 -0
- data/lib/ams_lazy_relationships/loaders/association.rb +13 -3
- data/lib/ams_lazy_relationships/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf2c7b4fd222fcde15c3f1accd9784c421455d988bf4ec6bf2c76b4029cf2718
|
4
|
+
data.tar.gz: 306b361e74fa64697a046c9b67d0b5dd1bdbfc930c2a77df4e443fc65bb2de6a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36ed2e0404138db614928261d8dfd771b185fa9fd62dc6e091e5ee037b05bf3fec3d6a0e20fdd254ac100ffbbcc2ee175c9e16296d0a2120fa47968f2c15ef5d
|
7
|
+
data.tar.gz: 0eac844f0f061f4e9769cea6835de6eebc75415d3fefc5aff82c2b838bef9c22609188d24ba8bd2b33851e0ce2c0fc8e19fef4ebc00f92e217e980394529fd3d
|
data/.travis.yml
CHANGED
@@ -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
|
data/CHANGELOG.md
CHANGED
@@ -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
|
|
data/Gemfile.lock
CHANGED
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
|
-
|
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
|
-
|
155
|
+
include_data :if_sideloaded
|
156
|
+
link :self, 'a link'
|
157
|
+
meta name: 'Dan Brown'
|
123
158
|
end
|
124
159
|
end
|
125
160
|
```
|
@@ -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
|
-
|
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
|
-
|
33
|
-
serializer
|
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
|
-
|
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,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
|
-
|
49
|
-
|
50
|
-
|
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
|
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.
|
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
|
+
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
|