pluckers 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/doc/usage/relationships.md +39 -0
- data/lib/pluckers/base.rb +1 -0
- data/lib/pluckers/features/active_record_3_2.rb +1 -0
- data/lib/pluckers/features/active_record_3_2/belongs_to_polymorphic_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_3_2/belongs_to_reflections.rb +2 -1
- data/lib/pluckers/features/active_record_4_0.rb +1 -0
- data/lib/pluckers/features/active_record_4_0/belongs_to_polymorphic_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_0/belongs_to_reflections.rb +2 -1
- data/lib/pluckers/features/active_record_4_1.rb +1 -0
- data/lib/pluckers/features/active_record_4_1/belongs_to_polymorphic_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_1/belongs_to_reflections.rb +2 -1
- data/lib/pluckers/features/active_record_4_2.rb +1 -0
- data/lib/pluckers/features/active_record_4_2/belongs_to_polymorphic_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_4_2/belongs_to_reflections.rb +2 -1
- data/lib/pluckers/features/active_record_5_0.rb +1 -0
- data/lib/pluckers/features/active_record_5_0/belongs_to_polymorphic_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_5_0/belongs_to_reflections.rb +2 -1
- data/lib/pluckers/features/active_record_5_1.rb +11 -10
- data/lib/pluckers/features/active_record_5_1/belongs_to_polymorphic_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_5_1/belongs_to_reflections.rb +2 -1
- data/lib/pluckers/features/base/belongs_to_polymorphic_reflections.rb +171 -0
- data/lib/pluckers/features/base/globalize.rb +4 -4
- data/lib/pluckers/features/base/has_many_reflections.rb +5 -0
- data/lib/pluckers/features/base/has_one_reflections.rb +6 -0
- data/lib/pluckers/features/base/simple_attributes.rb +1 -1
- data/lib/pluckers/version.rb +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27c7ad348b844a0a98107a9057632aba27f7f3ff
|
4
|
+
data.tar.gz: e0d5e20adb05224dbb3fa63b05dfd8b0592915c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f72b986f807d61bc2c0203d14911ab088ce4a268fd1474668bdc0c4458201deb22049e604b231f61811048d63e904ff70896cb362560081aa6a490104ec1737
|
7
|
+
data.tar.gz: a0fa164e3fbbe1343cae413746bc70fac4f6552548e4fc6293fad92023a9519a75e575a4f4769a8b482fe15b123686a6068d137a3ab9c0d28237137044cc1312
|
data/CHANGELOG
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -27,7 +27,7 @@ In this section you will learn
|
|
27
27
|
* [How to use a plucker and what do you obtain from it](./doc/usage/basics.md)
|
28
28
|
* [How to use your plucker with your globalized methods](./doc/usage/globalize.md)
|
29
29
|
* [How to rename your fetched attributes](./doc/usage/renaming.md)
|
30
|
-
* [How to use your plucker for traversing through relationships in a recursive way and obtain data from several tables without N+1 and with the minimum queries](./doc/usage/relationships.md)
|
30
|
+
* [How to use your plucker for traversing through relationships (even polymorphic ones!) in a recursive way and obtain data from several tables without N+1 and with the minimum queries](./doc/usage/relationships.md)
|
31
31
|
* [How to create your own plucker classes to encapsulate all your plucking options and logic](./doc/usage/extending.md)
|
32
32
|
|
33
33
|
## Development
|
data/doc/usage/relationships.md
CHANGED
@@ -50,6 +50,45 @@ Each element in the reflections options has a key and a hash of options. The key
|
|
50
50
|
|
51
51
|
This means that we can do everything in this "secondary" plucker. We can get globalize columns, we can rename... and we can also get another related models, giving us the ability to obtain a whole tree of models and objects in just one single point, with the minimum database queries required.
|
52
52
|
|
53
|
+
## Polymorphic relationships
|
54
|
+
|
55
|
+
Polymorphic belongs_to has always been a headache and a source of N+1 queries given you can perform any join or includes operations.
|
56
|
+
|
57
|
+
With pluckers you can configure how each model must be plucked, being able to pluck different information that will allow you to perform different login, with the minimum number of queries.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
Pluckers::Base.new(BlogPost.all, {
|
61
|
+
attributes: [:name],
|
62
|
+
reflections: {
|
63
|
+
subject: {
|
64
|
+
:Author => { attributes: [:name] }
|
65
|
+
:Category => { attributes: [:title] }
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}).pluck
|
69
|
+
```
|
70
|
+
```ruby
|
71
|
+
[
|
72
|
+
{
|
73
|
+
id: 1, name: "Lorem Ipsum", subject_id: 1, subject_type: "Author", subject: { id: 1, name: "someone" }
|
74
|
+
},
|
75
|
+
{
|
76
|
+
id: 2, name: "Lorem Ipsum 2", subject_id: 2, subject_type: "Author", subject: { id: 2, name: "another one" }
|
77
|
+
},
|
78
|
+
{
|
79
|
+
id: 3, name: "Lorem Ipsum 3", subject_id: 1, subject_type: "Category", subject: { id: 1, title: "gifs" }
|
80
|
+
},
|
81
|
+
{
|
82
|
+
id: 4, name: "Lorem Ipsum 4", subject_id: 2, subject_type: "Category", subject: { id: 1, name: "shiba gifs" }
|
83
|
+
},
|
84
|
+
{
|
85
|
+
id: 5, name: "Lorem Ipsum 5", subject_id: 1, subject_type: "BlogPost", subject: nil
|
86
|
+
}
|
87
|
+
]
|
88
|
+
```
|
89
|
+
|
90
|
+
The options for each model are standard plucker options, so you can perform the exact same operations you are about to see. This means you can filter the polymorphic relationship with a scope and, more importantly, you can do this in a recursive way.
|
91
|
+
|
53
92
|
## Foreign keys and minimum data plucked
|
54
93
|
|
55
94
|
Although in the examples we only show ids involved, relationships configured with different foreign keys can be fetched too as the configuration is read by the plucker to use the proper columns in both involved tables.
|
data/lib/pluckers/base.rb
CHANGED
@@ -157,6 +157,7 @@ module Pluckers
|
|
157
157
|
prepend Features::Globalize
|
158
158
|
prepend Features::SimpleAttributes
|
159
159
|
prepend Features::BelongsToReflections
|
160
|
+
prepend Features::BelongsToPolymorphicReflections
|
160
161
|
prepend Features::HasManyReflections
|
161
162
|
prepend Features::HasManyThroughReflections
|
162
163
|
prepend Features::HasAndBelongsToManyReflections
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'active_record_3_2/simple_attributes'
|
2
2
|
require_relative 'active_record_3_2/belongs_to_reflections'
|
3
|
+
require_relative 'active_record_3_2/belongs_to_polymorphic_reflections'
|
3
4
|
require_relative 'active_record_3_2/has_many_reflections'
|
4
5
|
require_relative 'active_record_3_2/has_many_through_reflections'
|
5
6
|
require_relative 'active_record_3_2/has_and_belongs_to_many_reflections'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../base/belongs_to_polymorphic_reflections'
|
2
|
+
|
3
|
+
module Pluckers
|
4
|
+
module Features
|
5
|
+
module BelongsToPolymorphicReflections
|
6
|
+
|
7
|
+
def active_record_belongs_to_polymorphic_reflection? reflection
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
9
|
+
reflection.macro == :belongs_to &&
|
10
|
+
reflection.options[:polymorphic]
|
11
|
+
end
|
12
|
+
|
13
|
+
include Pluckers::Features::Base::BelongsToPolymorphicReflections
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,7 +6,8 @@ module Pluckers
|
|
6
6
|
|
7
7
|
def active_record_belongs_to_reflection? reflection
|
8
8
|
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
9
|
-
reflection.macro == :belongs_to
|
9
|
+
reflection.macro == :belongs_to &&
|
10
|
+
!reflection.options[:polymorphic]
|
10
11
|
end
|
11
12
|
|
12
13
|
include Pluckers::Features::Base::BelongsToReflections
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'active_record_4_0/simple_attributes'
|
2
2
|
require_relative 'active_record_4_0/belongs_to_reflections'
|
3
|
+
require_relative 'active_record_4_0/belongs_to_polymorphic_reflections'
|
3
4
|
require_relative 'active_record_4_0/has_many_reflections'
|
4
5
|
require_relative 'active_record_4_0/has_many_through_reflections'
|
5
6
|
require_relative 'active_record_4_0/has_and_belongs_to_many_reflections'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../base/belongs_to_polymorphic_reflections'
|
2
|
+
|
3
|
+
module Pluckers
|
4
|
+
module Features
|
5
|
+
module BelongsToPolymorphicReflections
|
6
|
+
|
7
|
+
def active_record_belongs_to_polymorphic_reflection? reflection
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
9
|
+
reflection.macro == :belongs_to &&
|
10
|
+
reflection.options[:polymorphic]
|
11
|
+
end
|
12
|
+
|
13
|
+
include Pluckers::Features::Base::BelongsToPolymorphicReflections
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,7 +6,8 @@ module Pluckers
|
|
6
6
|
|
7
7
|
def active_record_belongs_to_reflection? reflection
|
8
8
|
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
9
|
-
reflection.macro == :belongs_to
|
9
|
+
reflection.macro == :belongs_to&&
|
10
|
+
!reflection.options[:polymorphic]
|
10
11
|
end
|
11
12
|
|
12
13
|
include Pluckers::Features::Base::BelongsToReflections
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'active_record_4_1/simple_attributes'
|
2
2
|
require_relative 'active_record_4_1/belongs_to_reflections'
|
3
|
+
require_relative 'active_record_4_1/belongs_to_polymorphic_reflections'
|
3
4
|
require_relative 'active_record_4_1/has_many_reflections'
|
4
5
|
require_relative 'active_record_4_1/has_many_through_reflections'
|
5
6
|
require_relative 'active_record_4_1/has_and_belongs_to_many_reflections'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../base/belongs_to_polymorphic_reflections'
|
2
|
+
|
3
|
+
module Pluckers
|
4
|
+
module Features
|
5
|
+
module BelongsToPolymorphicReflections
|
6
|
+
|
7
|
+
def active_record_belongs_to_polymorphic_reflection? reflection
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
9
|
+
reflection.macro == :belongs_to &&
|
10
|
+
reflection.options[:polymorphic]
|
11
|
+
end
|
12
|
+
|
13
|
+
include Pluckers::Features::Base::BelongsToPolymorphicReflections
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,7 +6,8 @@ module Pluckers
|
|
6
6
|
|
7
7
|
def active_record_belongs_to_reflection? reflection
|
8
8
|
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
9
|
-
reflection.macro == :belongs_to
|
9
|
+
reflection.macro == :belongs_to &&
|
10
|
+
!reflection.options[:polymorphic]
|
10
11
|
end
|
11
12
|
|
12
13
|
include Pluckers::Features::Base::BelongsToReflections
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'active_record_4_2/simple_attributes'
|
2
2
|
require_relative 'active_record_4_2/belongs_to_reflections'
|
3
|
+
require_relative 'active_record_4_2/belongs_to_polymorphic_reflections'
|
3
4
|
require_relative 'active_record_4_2/has_many_reflections'
|
4
5
|
require_relative 'active_record_4_2/has_many_through_reflections'
|
5
6
|
require_relative 'active_record_4_2/has_and_belongs_to_many_reflections'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../base/belongs_to_polymorphic_reflections'
|
2
|
+
|
3
|
+
module Pluckers
|
4
|
+
module Features
|
5
|
+
module BelongsToPolymorphicReflections
|
6
|
+
|
7
|
+
def active_record_belongs_to_polymorphic_reflection? reflection
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) &&
|
9
|
+
reflection.options[:polymorphic]
|
10
|
+
end
|
11
|
+
|
12
|
+
include Pluckers::Features::Base::BelongsToPolymorphicReflections
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -5,7 +5,8 @@ module Pluckers
|
|
5
5
|
module BelongsToReflections
|
6
6
|
|
7
7
|
def active_record_belongs_to_reflection? reflection
|
8
|
-
reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection)
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) &&
|
9
|
+
!reflection.options[:polymorphic]
|
9
10
|
end
|
10
11
|
|
11
12
|
include Pluckers::Features::Base::BelongsToReflections
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'active_record_5_0/simple_attributes'
|
2
2
|
require_relative 'active_record_5_0/belongs_to_reflections'
|
3
|
+
require_relative 'active_record_5_0/belongs_to_polymorphic_reflections'
|
3
4
|
require_relative 'active_record_5_0/has_many_reflections'
|
4
5
|
require_relative 'active_record_5_0/has_many_through_reflections'
|
5
6
|
require_relative 'active_record_5_0/has_and_belongs_to_many_reflections'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../base/belongs_to_polymorphic_reflections'
|
2
|
+
|
3
|
+
module Pluckers
|
4
|
+
module Features
|
5
|
+
module BelongsToPolymorphicReflections
|
6
|
+
|
7
|
+
def active_record_belongs_to_polymorphic_reflection? reflection
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) &&
|
9
|
+
reflection.options[:polymorphic]
|
10
|
+
end
|
11
|
+
|
12
|
+
include Pluckers::Features::Base::BelongsToPolymorphicReflections
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -5,7 +5,8 @@ module Pluckers
|
|
5
5
|
module BelongsToReflections
|
6
6
|
|
7
7
|
def active_record_belongs_to_reflection? reflection
|
8
|
-
reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection)
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) &&
|
9
|
+
!reflection.options[:polymorphic]
|
9
10
|
end
|
10
11
|
|
11
12
|
include Pluckers::Features::Base::BelongsToReflections
|
@@ -1,10 +1,11 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
6
|
-
require_relative '
|
7
|
-
require_relative '
|
8
|
-
require_relative '
|
9
|
-
require_relative '
|
10
|
-
require_relative '
|
1
|
+
require_relative 'active_record_5_1/simple_attributes'
|
2
|
+
require_relative 'active_record_5_1/belongs_to_reflections'
|
3
|
+
require_relative 'active_record_5_1/belongs_to_polymorphic_reflections'
|
4
|
+
require_relative 'active_record_5_1/has_many_reflections'
|
5
|
+
require_relative 'active_record_5_1/has_many_through_reflections'
|
6
|
+
require_relative 'active_record_5_1/has_and_belongs_to_many_reflections'
|
7
|
+
require_relative 'active_record_5_1/has_one_reflections'
|
8
|
+
require_relative 'active_record_5_1/has_one_through_reflections'
|
9
|
+
require_relative 'active_record_5_1/renaming'
|
10
|
+
require_relative 'active_record_5_1/globalize'
|
11
|
+
require_relative 'active_record_5_1/pluck'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../base/belongs_to_polymorphic_reflections'
|
2
|
+
|
3
|
+
module Pluckers
|
4
|
+
module Features
|
5
|
+
module BelongsToPolymorphicReflections
|
6
|
+
|
7
|
+
def active_record_belongs_to_polymorphic_reflection? reflection
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) &&
|
9
|
+
reflection.options[:polymorphic]
|
10
|
+
end
|
11
|
+
|
12
|
+
include Pluckers::Features::Base::BelongsToPolymorphicReflections
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -5,7 +5,8 @@ module Pluckers
|
|
5
5
|
module BelongsToReflections
|
6
6
|
|
7
7
|
def active_record_belongs_to_reflection? reflection
|
8
|
-
reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection)
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) &&
|
9
|
+
!reflection.options[:polymorphic]
|
9
10
|
end
|
10
11
|
|
11
12
|
include Pluckers::Features::Base::BelongsToReflections
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module Pluckers
|
2
|
+
##
|
3
|
+
# This module groups diferent modules that will configure and build the
|
4
|
+
# results for a specific kind of information (attributes, translations,
|
5
|
+
# relations...)
|
6
|
+
#
|
7
|
+
# All this modules will have two methods, one for configuration (e.g, attributes
|
8
|
+
# to be included in the real pluck) and one for building the final results
|
9
|
+
module Features
|
10
|
+
|
11
|
+
module Base
|
12
|
+
|
13
|
+
##
|
14
|
+
# This module implements plucking belongs_to polymorphic relationships in
|
15
|
+
# a recursive way.
|
16
|
+
#
|
17
|
+
# The options used in this feature are:
|
18
|
+
#
|
19
|
+
# * reflections: A hash of the reflections we will pluck recursively. The
|
20
|
+
# key of this hash will be the name of the reflection and the value is
|
21
|
+
# another hash of options.
|
22
|
+
#
|
23
|
+
# In the case of a polymorphic relationship, this options will be a hash
|
24
|
+
# where you will set the plucking options for each different
|
25
|
+
# available model. Keys of the hash wil be names of the models and
|
26
|
+
# the values will be the regular options for a standard reflection:
|
27
|
+
#
|
28
|
+
# - scope: You can limit the scope of the objects plucked. E.g, you
|
29
|
+
# could use Author.active instead of Author.all. Notice that .all is
|
30
|
+
# the default.
|
31
|
+
#
|
32
|
+
# - plucker: You can use a custom plucker instead of Pluckers::Base in
|
33
|
+
# case you want any specific logic. Pluckers::Base is the default
|
34
|
+
# one.
|
35
|
+
#
|
36
|
+
# - Any other option will be passed to the plucker, so you can send any
|
37
|
+
# other regular option such as attributes, custom ones or even more
|
38
|
+
# reflections. Recursivity FTW!! (even in polymorphic relations)
|
39
|
+
#
|
40
|
+
module BelongsToPolymorphicReflections
|
41
|
+
|
42
|
+
|
43
|
+
##
|
44
|
+
# Here we obtain the belongs_to reflections to include in the pluck
|
45
|
+
# operation and also include the relation foreign key in the attributes to
|
46
|
+
# pluck for this model.
|
47
|
+
def configure_query
|
48
|
+
super
|
49
|
+
|
50
|
+
pluck_reflections = @options[:reflections] || {}
|
51
|
+
|
52
|
+
return if pluck_reflections.blank?
|
53
|
+
|
54
|
+
@belongs_to_polymorphic_reflections = { }
|
55
|
+
|
56
|
+
# We iterate through the class reflections passed as options
|
57
|
+
@klass_reflections.slice(*pluck_reflections.keys).
|
58
|
+
# And select those that are BelongsTo
|
59
|
+
select{|_, r| active_record_belongs_to_polymorphic_reflection?(r) }.
|
60
|
+
# And store them in the belongs_to_reflection hash that will be used later
|
61
|
+
each do |name, reflection|
|
62
|
+
name = name.to_sym
|
63
|
+
@belongs_to_polymorphic_reflections[name] = pluck_reflections[name]
|
64
|
+
end
|
65
|
+
|
66
|
+
# First thing we do is to include the foreign key in the attributes to
|
67
|
+
# pluck array, so the base plucker plucks them
|
68
|
+
@belongs_to_polymorphic_reflections.each do |name, _|
|
69
|
+
|
70
|
+
foreign_key_name = @klass_reflections[name].foreign_key
|
71
|
+
@attributes_to_pluck << {
|
72
|
+
name: foreign_key_name.to_sym,
|
73
|
+
sql: foreign_key_name
|
74
|
+
}
|
75
|
+
|
76
|
+
foreign_type = @klass_reflections[name].foreign_type
|
77
|
+
@attributes_to_pluck << {
|
78
|
+
name: foreign_type.to_sym,
|
79
|
+
sql: foreign_type
|
80
|
+
}
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# In this method we get the reflections and for each one creates and
|
88
|
+
# executes a new plucker.
|
89
|
+
#
|
90
|
+
# This pluck gives the whole process a recursive character and options
|
91
|
+
# for that plucker may be passed in the options hash.
|
92
|
+
def build_results
|
93
|
+
super
|
94
|
+
|
95
|
+
return if @belongs_to_polymorphic_reflections.blank?
|
96
|
+
# For each reflection
|
97
|
+
@belongs_to_polymorphic_reflections.each do |name, reflection|
|
98
|
+
# As an example we will imagine that we are plucking BlogPosts and
|
99
|
+
# this relation is the Subject
|
100
|
+
|
101
|
+
# First, we get the meta information about the reflection
|
102
|
+
klass_reflection = @klass_reflections[name]
|
103
|
+
|
104
|
+
|
105
|
+
reflection_primary_key = klass_reflection.active_record_primary_key.to_sym
|
106
|
+
reflection_foreign_key = klass_reflection.foreign_key.to_sym
|
107
|
+
reflection_foreign_type = klass_reflection.foreign_type.to_sym
|
108
|
+
|
109
|
+
# Now, we group all the already plucked _type and _id attributes, so
|
110
|
+
# we can pluck the polymorphic models
|
111
|
+
polymporphic_models = {}
|
112
|
+
|
113
|
+
@results.each do |_, r|
|
114
|
+
next if r[reflection_foreign_type].nil? || r[reflection_foreign_key].nil?
|
115
|
+
polymporphic_models[r[reflection_foreign_type]] ||= []
|
116
|
+
polymporphic_models[r[reflection_foreign_type]] << r[reflection_foreign_key]
|
117
|
+
end
|
118
|
+
|
119
|
+
# Now we have a hash like {
|
120
|
+
# "Category" => [1, 2, 3], "Author" => [4, 2, 8]
|
121
|
+
# }
|
122
|
+
|
123
|
+
# We initialize so we return a nil if there are no record related
|
124
|
+
@results.each do |_,result|
|
125
|
+
result[name] = nil
|
126
|
+
end
|
127
|
+
|
128
|
+
polymporphic_models.each do |model_name, model_ids|
|
129
|
+
|
130
|
+
model_options = reflection[model_name.to_sym]
|
131
|
+
|
132
|
+
# If there are no options for a model we don't pluck them
|
133
|
+
next if model_options.nil?
|
134
|
+
|
135
|
+
# initialize some options such as the plucker or the scope of the pluck
|
136
|
+
scope = model_options[:scope] || model_name.constantize.send(all_method)
|
137
|
+
plucker = model_options[:plucker] || Pluckers::Base
|
138
|
+
|
139
|
+
# And now we create the plucker. Notice that we add a where to the
|
140
|
+
# scope, so we filter the records to pluck as we only get those with
|
141
|
+
# an id in the set of the foreign keys of the records already
|
142
|
+
# plucked by the base plucker
|
143
|
+
#
|
144
|
+
# In our Example we would be doing something like
|
145
|
+
# Author.all.where(id: author_ids)
|
146
|
+
reflection_plucker = plucker.new scope.where(
|
147
|
+
reflection_primary_key => model_ids
|
148
|
+
),
|
149
|
+
model_options
|
150
|
+
|
151
|
+
# And now pluck the related class and process the results
|
152
|
+
reflection_plucker.pluck.each do |r|
|
153
|
+
# For each related result (Author or Category) we search those
|
154
|
+
# records (BlogPost) that are related (post.subject_id ==
|
155
|
+
# author.id o post.subject_id == category.id) and insert them in
|
156
|
+
# the relationship attributes
|
157
|
+
@results.each do |_,result|
|
158
|
+
if result[reflection_foreign_key] == r[reflection_primary_key] &&
|
159
|
+
result[reflection_foreign_type] == model_name
|
160
|
+
result[name] = r
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -70,8 +70,8 @@ module Pluckers
|
|
70
70
|
|
71
71
|
fallbacks.each do |locale|
|
72
72
|
@records = @records.joins(
|
73
|
-
"LEFT OUTER JOIN #{translation_table_name} AS locale_#{locale}_translation ON (
|
74
|
-
#{@records.klass.table_name}.id = locale_#{locale}_translation.#{translation_foreign_key} AND
|
73
|
+
"LEFT OUTER JOIN #{@records.klass.connection.quote_table_name translation_table_name} AS locale_#{locale}_translation ON (
|
74
|
+
#{@records.klass.connection.quote_table_name @records.klass.table_name}.id = locale_#{locale}_translation.#{translation_foreign_key} AND
|
75
75
|
locale_#{locale}_translation.locale = '#{locale}'
|
76
76
|
)")
|
77
77
|
|
@@ -93,8 +93,8 @@ module Pluckers
|
|
93
93
|
# We add the locales that are not fallback
|
94
94
|
unless fallbacks.include? locale
|
95
95
|
@records = @records.joins(
|
96
|
-
"LEFT OUTER JOIN #{translation_table_name} AS locale_#{locale}_translation ON (
|
97
|
-
#{@records.klass.table_name}.id = locale_#{locale}_translation.#{translation_foreign_key} AND
|
96
|
+
"LEFT OUTER JOIN #{@records.klass.connection.quote_table_name translation_table_name} AS locale_#{locale}_translation ON (
|
97
|
+
#{@records.klass.connection.quote_table_name @records.klass.table_name}.id = locale_#{locale}_translation.#{translation_foreign_key} AND
|
98
98
|
locale_#{locale}_translation.locale = '#{locale}'
|
99
99
|
)")
|
100
100
|
end
|
@@ -102,6 +102,11 @@ module Pluckers
|
|
102
102
|
# key as we will need it to relate the records
|
103
103
|
reflection[:attributes] |= [klass_reflection.foreign_key.to_sym] if reflection[:attributes]
|
104
104
|
|
105
|
+
# If the has_many is an :as relationship (inverse of a polymorphic
|
106
|
+
# one) we should filter the ones with the right class
|
107
|
+
if klass_reflection.options[:as]
|
108
|
+
scope = scope.where(klass_reflection.type => klass_reflection.active_record.class_name)
|
109
|
+
end
|
105
110
|
|
106
111
|
# And now we create the plucker. Notice that we add a where to the
|
107
112
|
# scope, so we filter the records to pluck as we only get those with
|
@@ -85,6 +85,12 @@ module Pluckers
|
|
85
85
|
# key as we will need it to relate the records
|
86
86
|
reflection[:attributes] |= [klass_reflection.foreign_key.to_sym] if reflection[:attributes]
|
87
87
|
|
88
|
+
# If the has_one is an :as relationship (inverse of a polymorphic
|
89
|
+
# one) we should filter the ones with the right class
|
90
|
+
if klass_reflection.options[:as]
|
91
|
+
scope = scope.where(klass_reflection.type => klass_reflection.active_record.class_name)
|
92
|
+
end
|
93
|
+
|
88
94
|
# And now we create the plucker. Notice that we add a where to the
|
89
95
|
# scope, so we filter the records to pluck as we only get those with
|
90
96
|
# an id in the set of the foreign keys of the records already
|
@@ -41,7 +41,7 @@ module Pluckers
|
|
41
41
|
|
42
42
|
simple_attributes = plucker_attributes & klass_attributes
|
43
43
|
|
44
|
-
@attributes_to_pluck += simple_attributes.map {|f| { name: f, sql: "
|
44
|
+
@attributes_to_pluck += simple_attributes.map {|f| { name: f, sql: "#{@records.klass.connection.quote_table_name @records.table_name}.#{f}" }}
|
45
45
|
|
46
46
|
end
|
47
47
|
|
data/lib/pluckers/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pluckers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David J. Brenes
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- lib/pluckers.rb
|
142
142
|
- lib/pluckers/base.rb
|
143
143
|
- lib/pluckers/features/active_record_3_2.rb
|
144
|
+
- lib/pluckers/features/active_record_3_2/belongs_to_polymorphic_reflections.rb
|
144
145
|
- lib/pluckers/features/active_record_3_2/belongs_to_reflections.rb
|
145
146
|
- lib/pluckers/features/active_record_3_2/globalize.rb
|
146
147
|
- lib/pluckers/features/active_record_3_2/has_and_belongs_to_many_reflections.rb
|
@@ -152,6 +153,7 @@ files:
|
|
152
153
|
- lib/pluckers/features/active_record_3_2/renaming.rb
|
153
154
|
- lib/pluckers/features/active_record_3_2/simple_attributes.rb
|
154
155
|
- lib/pluckers/features/active_record_4_0.rb
|
156
|
+
- lib/pluckers/features/active_record_4_0/belongs_to_polymorphic_reflections.rb
|
155
157
|
- lib/pluckers/features/active_record_4_0/belongs_to_reflections.rb
|
156
158
|
- lib/pluckers/features/active_record_4_0/globalize.rb
|
157
159
|
- lib/pluckers/features/active_record_4_0/has_and_belongs_to_many_reflections.rb
|
@@ -163,6 +165,7 @@ files:
|
|
163
165
|
- lib/pluckers/features/active_record_4_0/renaming.rb
|
164
166
|
- lib/pluckers/features/active_record_4_0/simple_attributes.rb
|
165
167
|
- lib/pluckers/features/active_record_4_1.rb
|
168
|
+
- lib/pluckers/features/active_record_4_1/belongs_to_polymorphic_reflections.rb
|
166
169
|
- lib/pluckers/features/active_record_4_1/belongs_to_reflections.rb
|
167
170
|
- lib/pluckers/features/active_record_4_1/globalize.rb
|
168
171
|
- lib/pluckers/features/active_record_4_1/has_and_belongs_to_many_reflections.rb
|
@@ -174,6 +177,7 @@ files:
|
|
174
177
|
- lib/pluckers/features/active_record_4_1/renaming.rb
|
175
178
|
- lib/pluckers/features/active_record_4_1/simple_attributes.rb
|
176
179
|
- lib/pluckers/features/active_record_4_2.rb
|
180
|
+
- lib/pluckers/features/active_record_4_2/belongs_to_polymorphic_reflections.rb
|
177
181
|
- lib/pluckers/features/active_record_4_2/belongs_to_reflections.rb
|
178
182
|
- lib/pluckers/features/active_record_4_2/globalize.rb
|
179
183
|
- lib/pluckers/features/active_record_4_2/has_and_belongs_to_many_reflections.rb
|
@@ -185,6 +189,7 @@ files:
|
|
185
189
|
- lib/pluckers/features/active_record_4_2/renaming.rb
|
186
190
|
- lib/pluckers/features/active_record_4_2/simple_attributes.rb
|
187
191
|
- lib/pluckers/features/active_record_5_0.rb
|
192
|
+
- lib/pluckers/features/active_record_5_0/belongs_to_polymorphic_reflections.rb
|
188
193
|
- lib/pluckers/features/active_record_5_0/belongs_to_reflections.rb
|
189
194
|
- lib/pluckers/features/active_record_5_0/globalize.rb
|
190
195
|
- lib/pluckers/features/active_record_5_0/has_and_belongs_to_many_reflections.rb
|
@@ -196,6 +201,7 @@ files:
|
|
196
201
|
- lib/pluckers/features/active_record_5_0/renaming.rb
|
197
202
|
- lib/pluckers/features/active_record_5_0/simple_attributes.rb
|
198
203
|
- lib/pluckers/features/active_record_5_1.rb
|
204
|
+
- lib/pluckers/features/active_record_5_1/belongs_to_polymorphic_reflections.rb
|
199
205
|
- lib/pluckers/features/active_record_5_1/belongs_to_reflections.rb
|
200
206
|
- lib/pluckers/features/active_record_5_1/globalize.rb
|
201
207
|
- lib/pluckers/features/active_record_5_1/has_and_belongs_to_many_reflections.rb
|
@@ -206,6 +212,7 @@ files:
|
|
206
212
|
- lib/pluckers/features/active_record_5_1/pluck.rb
|
207
213
|
- lib/pluckers/features/active_record_5_1/renaming.rb
|
208
214
|
- lib/pluckers/features/active_record_5_1/simple_attributes.rb
|
215
|
+
- lib/pluckers/features/base/belongs_to_polymorphic_reflections.rb
|
209
216
|
- lib/pluckers/features/base/belongs_to_reflections.rb
|
210
217
|
- lib/pluckers/features/base/globalize.rb
|
211
218
|
- lib/pluckers/features/base/has_and_belongs_to_many_reflections.rb
|