pluckers 1.0.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 +7 -0
- data/.gitignore +51 -0
- data/Appraisals +22 -0
- data/CHANGELOG +7 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +56 -0
- data/LICENSE +674 -0
- data/README.md +40 -0
- data/Rakefile +10 -0
- data/circle.yml +15 -0
- data/doc/idea.md +49 -0
- data/doc/usage/basics.md +46 -0
- data/doc/usage/extending.md +109 -0
- data/doc/usage/globalize.md +54 -0
- data/doc/usage/relationships.md +216 -0
- data/doc/usage/renaming.md +26 -0
- data/lib/pluckers/base.rb +166 -0
- data/lib/pluckers/features/active_record_3_2/belongs_to_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_3_2/globalize.rb +11 -0
- data/lib/pluckers/features/active_record_3_2/has_and_belongs_to_many_reflections.rb +40 -0
- data/lib/pluckers/features/active_record_3_2/has_many_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_3_2/has_many_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_3_2/has_one_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_3_2/has_one_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_3_2/pluck.rb +26 -0
- data/lib/pluckers/features/active_record_3_2/renaming.rb +11 -0
- data/lib/pluckers/features/active_record_3_2/simple_attributes.rb +11 -0
- data/lib/pluckers/features/active_record_3_2.rb +10 -0
- data/lib/pluckers/features/active_record_4_0/belongs_to_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_4_0/globalize.rb +11 -0
- data/lib/pluckers/features/active_record_4_0/has_and_belongs_to_many_reflections.rb +40 -0
- data/lib/pluckers/features/active_record_4_0/has_many_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_4_0/has_many_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_0/has_one_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_0/has_one_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_0/pluck.rb +11 -0
- data/lib/pluckers/features/active_record_4_0/renaming.rb +11 -0
- data/lib/pluckers/features/active_record_4_0/simple_attributes.rb +11 -0
- data/lib/pluckers/features/active_record_4_0.rb +10 -0
- data/lib/pluckers/features/active_record_4_1/belongs_to_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_4_1/globalize.rb +11 -0
- data/lib/pluckers/features/active_record_4_1/has_and_belongs_to_many_reflections.rb +40 -0
- data/lib/pluckers/features/active_record_4_1/has_many_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_4_1/has_many_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_1/has_one_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_1/has_one_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_1/pluck.rb +11 -0
- data/lib/pluckers/features/active_record_4_1/renaming.rb +11 -0
- data/lib/pluckers/features/active_record_4_1/simple_attributes.rb +11 -0
- data/lib/pluckers/features/active_record_4_1.rb +10 -0
- data/lib/pluckers/features/active_record_4_2/belongs_to_reflections.rb +15 -0
- data/lib/pluckers/features/active_record_4_2/globalize.rb +11 -0
- data/lib/pluckers/features/active_record_4_2/has_and_belongs_to_many_reflections.rb +39 -0
- data/lib/pluckers/features/active_record_4_2/has_many_reflections.rb +15 -0
- data/lib/pluckers/features/active_record_4_2/has_many_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_2/has_one_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_4_2/has_one_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_4_2/pluck.rb +11 -0
- data/lib/pluckers/features/active_record_4_2/renaming.rb +11 -0
- data/lib/pluckers/features/active_record_4_2/simple_attributes.rb +11 -0
- data/lib/pluckers/features/active_record_4_2.rb +10 -0
- data/lib/pluckers/features/active_record_5_0/belongs_to_reflections.rb +15 -0
- data/lib/pluckers/features/active_record_5_0/globalize.rb +11 -0
- data/lib/pluckers/features/active_record_5_0/has_and_belongs_to_many_reflections.rb +39 -0
- data/lib/pluckers/features/active_record_5_0/has_many_reflections.rb +15 -0
- data/lib/pluckers/features/active_record_5_0/has_many_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_5_0/has_one_reflections.rb +16 -0
- data/lib/pluckers/features/active_record_5_0/has_one_through_reflections.rb +17 -0
- data/lib/pluckers/features/active_record_5_0/pluck.rb +11 -0
- data/lib/pluckers/features/active_record_5_0/renaming.rb +11 -0
- data/lib/pluckers/features/active_record_5_0/simple_attributes.rb +11 -0
- data/lib/pluckers/features/active_record_5_0.rb +10 -0
- data/lib/pluckers/features/base/belongs_to_reflections.rb +131 -0
- data/lib/pluckers/features/base/globalize.rb +116 -0
- data/lib/pluckers/features/base/has_and_belongs_to_many_reflections.rb +190 -0
- data/lib/pluckers/features/base/has_many_reflections.rb +193 -0
- data/lib/pluckers/features/base/has_many_through_reflections.rb +131 -0
- data/lib/pluckers/features/base/has_one_reflections.rb +122 -0
- data/lib/pluckers/features/base/has_one_through_reflections.rb +129 -0
- data/lib/pluckers/features/base/pluck.rb +30 -0
- data/lib/pluckers/features/base/renaming.rb +55 -0
- data/lib/pluckers/features/base/simple_attributes.rb +64 -0
- data/lib/pluckers/version.rb +3 -0
- data/lib/pluckers.rb +7 -0
- data/pluckers.gemspec +38 -0
- metadata +236 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
active_record_version = ActiveRecord.respond_to?(:version) ? ActiveRecord.version : Gem::Version.new(ActiveRecord::VERSION::STRING)
|
|
2
|
+
|
|
3
|
+
if active_record_version > Gem::Version.new("4.2") && active_record_version < Gem::Version.new("5.0")
|
|
4
|
+
require_relative 'features/active_record_4_2'
|
|
5
|
+
elsif active_record_version > Gem::Version.new("4.1") && active_record_version < Gem::Version.new("4.2")
|
|
6
|
+
require_relative 'features/active_record_4_1'
|
|
7
|
+
elsif active_record_version > Gem::Version.new("4.0") && active_record_version < Gem::Version.new("4.1")
|
|
8
|
+
require_relative 'features/active_record_4_0'
|
|
9
|
+
elsif active_record_version > Gem::Version.new("5.0") && active_record_version < Gem::Version.new("5.1")
|
|
10
|
+
require_relative 'features/active_record_5_0'
|
|
11
|
+
elsif active_record_version > Gem::Version.new("3.2") && active_record_version < Gem::Version.new("4.0")
|
|
12
|
+
require_relative 'features/active_record_3_2'
|
|
13
|
+
else
|
|
14
|
+
require_relative 'features/active_record_4_2'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module Pluckers
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# This is the base class for all pluckers.
|
|
21
|
+
#
|
|
22
|
+
# It receives all the configuration in the `initialize` method and performs
|
|
23
|
+
# all the sql queries and hash building inside the `pluck` method.
|
|
24
|
+
class Base
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
# In this attribute we store the ActiveRecord Relation we use to fetch
|
|
28
|
+
# information from the database
|
|
29
|
+
attr_reader :records
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# In the initialize method we recive all the options for the plucker.
|
|
33
|
+
#
|
|
34
|
+
# First, we receive an ActiveRecord Relation. It can be any ActiveRecord
|
|
35
|
+
# scope such as `BlogPost.all` or `BlogPost.published`. If we want to
|
|
36
|
+
# pluck a particular object we could pass `BlogPost.where(id: post.id )`
|
|
37
|
+
# so we have an ActiveRecord relation.
|
|
38
|
+
#
|
|
39
|
+
# The options hash allows us to send a lot of configuration that will be
|
|
40
|
+
# used by all the features and subclasses to decorate the very basic
|
|
41
|
+
# behaviour.
|
|
42
|
+
#
|
|
43
|
+
# Currently, the options supported by the features included in this base
|
|
44
|
+
# plucker are:
|
|
45
|
+
#
|
|
46
|
+
# * attributes: Names of attributes of the objects to be plucked. This
|
|
47
|
+
# attributes should be the names of the columns in the database. If we are
|
|
48
|
+
# using Globalize these attributes can also be the names of the translated
|
|
49
|
+
# attributes by Globalize.
|
|
50
|
+
#
|
|
51
|
+
# * attributes_with_locale: A hash when the key is a locale and the value
|
|
52
|
+
# is an array of attributes to pluck. As a result we will have a series of
|
|
53
|
+
# attributes with the name following the syntax attreibute_locale. E.g: The
|
|
54
|
+
# option could be { es: [:name], en: [:name, :location]} and we would obtain
|
|
55
|
+
# :name_es, :name_en and :location_en keys in the hash result
|
|
56
|
+
#
|
|
57
|
+
# * renames: A hash of the attributes/reflections/whatever that will be
|
|
58
|
+
# renamed. The key is the old name and the value is the new name.
|
|
59
|
+
#
|
|
60
|
+
# * reflections: A hash of the reflections we will pluck recursively. The
|
|
61
|
+
# key of this hash will be the name of the reflection and the value is
|
|
62
|
+
# another hash of options.
|
|
63
|
+
#
|
|
64
|
+
# - scope: You can limit the scope of the objects plucked. E.g, you
|
|
65
|
+
# could use Author.active instead of Author.all. Notice that .all is
|
|
66
|
+
# the default.
|
|
67
|
+
#
|
|
68
|
+
# - plucker: You can use a custom plucker instead of Pluckers::Base in
|
|
69
|
+
# case you want any specific logic. Pluckers::Base is the default one.
|
|
70
|
+
#
|
|
71
|
+
# - only_ids: In has_many reflections we can get the _ids array instead
|
|
72
|
+
# of an array with hashes if we pass this option as true. If we do any
|
|
73
|
+
# fields or plucker option will be ignored.
|
|
74
|
+
#
|
|
75
|
+
# - Any other option will be passed to the plucker, so you can send any
|
|
76
|
+
# other regular option such as fields, custom ones or even more
|
|
77
|
+
# reflections. Recursivity FTW!!
|
|
78
|
+
#
|
|
79
|
+
# The options hash can be used by subclasses to decorate all this
|
|
80
|
+
# behaviour and send params inside the plucker.
|
|
81
|
+
def initialize records, options = {}
|
|
82
|
+
@records = records
|
|
83
|
+
@options = options
|
|
84
|
+
@features = @options.delete(:features)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
##
|
|
88
|
+
# This method performs all the sql and hash building according to the
|
|
89
|
+
# received configuration.
|
|
90
|
+
def pluck
|
|
91
|
+
return [] if @records.blank?
|
|
92
|
+
|
|
93
|
+
configure_query
|
|
94
|
+
|
|
95
|
+
build_results
|
|
96
|
+
|
|
97
|
+
# And return the results
|
|
98
|
+
@results.values
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
# In this base implementation we just reset all the query information.
|
|
103
|
+
# Features and subclasses must redefine this method if they are interested
|
|
104
|
+
# in adding some behaviour.
|
|
105
|
+
def configure_query
|
|
106
|
+
@query_to_pluck = @records
|
|
107
|
+
@attributes_to_pluck = [{ name: @query_to_pluck.primary_key.to_sym, sql: "\"#{@query_to_pluck.table_name}\".#{@query_to_pluck.primary_key}" }]
|
|
108
|
+
@results = {}
|
|
109
|
+
@klass_reflections = @query_to_pluck.reflections.with_indifferent_access
|
|
110
|
+
|
|
111
|
+
pluck_reflections = @options[:reflections] || {}
|
|
112
|
+
|
|
113
|
+
# Validate that all relations exists in the model
|
|
114
|
+
if (missing_reflections = pluck_reflections.symbolize_keys.keys - @klass_reflections.symbolize_keys.keys).any?
|
|
115
|
+
raise ArgumentError.new("Plucker reflections '#{missing_reflections.to_sentence}', are missing in #{@records.klass}")
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
##
|
|
120
|
+
# In this base implementation we perform the real pluck execution.
|
|
121
|
+
#
|
|
122
|
+
# The method collects all the attributes and columns to pluck and add it
|
|
123
|
+
# to the results array.
|
|
124
|
+
def build_results
|
|
125
|
+
|
|
126
|
+
# Now we uinq the attributes
|
|
127
|
+
@attributes_to_pluck.uniq!{|f| f[:name] }
|
|
128
|
+
|
|
129
|
+
# Obtain both the names and SQL columns
|
|
130
|
+
names_to_pluck = @attributes_to_pluck.map{|f| f[:name] }
|
|
131
|
+
sql_to_pluck = @attributes_to_pluck.map{|f| f[:sql] }
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# And perform the real ActiveRecord pluck.
|
|
135
|
+
pluck_records(sql_to_pluck).each_with_index do |record, index|
|
|
136
|
+
# After the pluck we have to create the hash for each record.
|
|
137
|
+
|
|
138
|
+
# If there's only a field we will not receive an array. But we need it
|
|
139
|
+
# so we built it.
|
|
140
|
+
record = [record] unless record.is_a? Array
|
|
141
|
+
# Now we zip it with the attribute names and create a hash. If we have
|
|
142
|
+
# have a record: [1, "Test title 1", "Test text 1"] and the
|
|
143
|
+
# names_to_pluck are [:id, :title, :text] we will end with {:id=>1,
|
|
144
|
+
# :title=>"Test title 1", :text=>"Test text 1"}
|
|
145
|
+
attributes_to_return = Hash[names_to_pluck.zip(record)]
|
|
146
|
+
|
|
147
|
+
# Now we store it in the results hash
|
|
148
|
+
@results[attributes_to_return[:id]] = attributes_to_return
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
include Features::Pluck
|
|
153
|
+
|
|
154
|
+
# Now we add all the base features
|
|
155
|
+
prepend Features::Globalize
|
|
156
|
+
prepend Features::SimpleAttributes
|
|
157
|
+
prepend Features::BelongsToReflections
|
|
158
|
+
prepend Features::HasManyReflections
|
|
159
|
+
prepend Features::HasManyThroughReflections
|
|
160
|
+
prepend Features::HasAndBelongsToManyReflections
|
|
161
|
+
prepend Features::HasOneReflections
|
|
162
|
+
prepend Features::HasOneThroughReflections
|
|
163
|
+
prepend Features::Renaming
|
|
164
|
+
|
|
165
|
+
end
|
|
166
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative '../base/belongs_to_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module BelongsToReflections
|
|
6
|
+
|
|
7
|
+
def active_record_belongs_to_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
reflection.macro == :belongs_to
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::BelongsToReflections
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require_relative '../base/has_and_belongs_to_many_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasAndBelongsToManyReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_and_belongs_to_many_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
(reflection.macro == :has_and_belongs_to_many)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def has_and_belongs_to_many_ids klass_reflection
|
|
13
|
+
|
|
14
|
+
# First, we get the the join table
|
|
15
|
+
join_table = Arel::Table.new(klass_reflection.options[:join_table])
|
|
16
|
+
|
|
17
|
+
# And now, the foreign_keys.
|
|
18
|
+
# In our example with BlogPost and Category they would be:
|
|
19
|
+
# model_foreign_key = blog_post_id
|
|
20
|
+
# related_model_foreign_key = category_id
|
|
21
|
+
model_foreign_key = klass_reflection.foreign_key
|
|
22
|
+
related_model_foreign_key = klass_reflection.association_foreign_key
|
|
23
|
+
|
|
24
|
+
# Now we query the join table so we get the two ids
|
|
25
|
+
ids_query = join_table.where(
|
|
26
|
+
join_table[model_foreign_key].in(@results.map{|_, r| r[:id] })
|
|
27
|
+
).project(
|
|
28
|
+
join_table[related_model_foreign_key],
|
|
29
|
+
join_table[model_foreign_key]
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
join_results = ActiveRecord::Base.connection.execute(ids_query.to_sql)
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
include Pluckers::Features::Base::HasAndBelongsToManyReflections
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative '../base/has_many_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasManyReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_many_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
(reflection.macro == :has_many)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasManyReflections
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative '../base/has_many_through_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasManyThroughReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_many_through_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) &&
|
|
9
|
+
(reflection.macro == :has_many)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasManyThroughReflections
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative '../base/has_one_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasOneReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_one_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
(reflection.macro == :has_one)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasOneReflections
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative '../base/has_one_through_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasOneThroughReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_one_through_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) &&
|
|
9
|
+
(reflection.macro == :has_one)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasOneThroughReflections
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Pluckers
|
|
2
|
+
module Features
|
|
3
|
+
module Pluck
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# In ActiveRecord 3.2 pluck only accepts one column. We have to go
|
|
7
|
+
# around it and not actually use the pluck method.
|
|
8
|
+
#
|
|
9
|
+
# Idea based on http://meltingice.net/2013/06/11/pluck-multiple-columns-rails/
|
|
10
|
+
def pluck_records(*fields_to_pluck)
|
|
11
|
+
records_clone = @records.clone
|
|
12
|
+
records_clone.select_values = fields_to_pluck
|
|
13
|
+
@records.connection.select_all(records_clone.arel).map do |attributes|
|
|
14
|
+
initialized_attributes = @records.klass.initialize_attributes(attributes)
|
|
15
|
+
attributes.each do |key, attribute|
|
|
16
|
+
attributes[key] = @records.klass.type_cast_attribute(key, initialized_attributes)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def all_method
|
|
22
|
+
:scoped
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require_relative 'active_record_3_2/simple_attributes'
|
|
2
|
+
require_relative 'active_record_3_2/belongs_to_reflections'
|
|
3
|
+
require_relative 'active_record_3_2/has_many_reflections'
|
|
4
|
+
require_relative 'active_record_3_2/has_many_through_reflections'
|
|
5
|
+
require_relative 'active_record_3_2/has_and_belongs_to_many_reflections'
|
|
6
|
+
require_relative 'active_record_3_2/has_one_reflections'
|
|
7
|
+
require_relative 'active_record_3_2/has_one_through_reflections'
|
|
8
|
+
require_relative 'active_record_3_2/renaming'
|
|
9
|
+
require_relative 'active_record_3_2/globalize'
|
|
10
|
+
require_relative 'active_record_3_2/pluck'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative '../base/belongs_to_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module BelongsToReflections
|
|
6
|
+
|
|
7
|
+
def active_record_belongs_to_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
reflection.macro == :belongs_to
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::BelongsToReflections
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require_relative '../base/has_and_belongs_to_many_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasAndBelongsToManyReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_and_belongs_to_many_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
(reflection.macro == :has_and_belongs_to_many)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def has_and_belongs_to_many_ids klass_reflection
|
|
13
|
+
|
|
14
|
+
# First, we get the the join table
|
|
15
|
+
join_table = Arel::Table.new(klass_reflection.join_table)
|
|
16
|
+
|
|
17
|
+
# And now, the foreign_keys.
|
|
18
|
+
# In our example with BlogPost and Category they would be:
|
|
19
|
+
# model_foreign_key = blog_post_id
|
|
20
|
+
# related_model_foreign_key = category_id
|
|
21
|
+
model_foreign_key = klass_reflection.foreign_key
|
|
22
|
+
related_model_foreign_key = klass_reflection.association_foreign_key
|
|
23
|
+
|
|
24
|
+
# Now we query the join table so we get the two ids
|
|
25
|
+
ids_query = join_table.where(
|
|
26
|
+
join_table[model_foreign_key].in(@results.map{|_, r| r[:id] })
|
|
27
|
+
).project(
|
|
28
|
+
join_table[related_model_foreign_key],
|
|
29
|
+
join_table[model_foreign_key]
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
join_results = ActiveRecord::Base.connection.execute(ids_query.to_sql)
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
include Pluckers::Features::Base::HasAndBelongsToManyReflections
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative '../base/has_many_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasManyReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_many_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
(reflection.macro == :has_many)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasManyReflections
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative '../base/has_many_through_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasManyThroughReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_many_through_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) &&
|
|
9
|
+
(reflection.macro == :has_many)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasManyThroughReflections
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative '../base/has_one_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasOneReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_one_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
(reflection.macro == :has_one)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasOneReflections
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative '../base/has_one_through_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasOneThroughReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_one_through_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) &&
|
|
9
|
+
(reflection.macro == :has_one)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasOneThroughReflections
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require_relative 'active_record_4_0/simple_attributes'
|
|
2
|
+
require_relative 'active_record_4_0/belongs_to_reflections'
|
|
3
|
+
require_relative 'active_record_4_0/has_many_reflections'
|
|
4
|
+
require_relative 'active_record_4_0/has_many_through_reflections'
|
|
5
|
+
require_relative 'active_record_4_0/has_and_belongs_to_many_reflections'
|
|
6
|
+
require_relative 'active_record_4_0/has_one_reflections'
|
|
7
|
+
require_relative 'active_record_4_0/has_one_through_reflections'
|
|
8
|
+
require_relative 'active_record_4_0/renaming'
|
|
9
|
+
require_relative 'active_record_4_0/globalize'
|
|
10
|
+
require_relative 'active_record_4_0/pluck'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative '../base/belongs_to_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module BelongsToReflections
|
|
6
|
+
|
|
7
|
+
def active_record_belongs_to_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
reflection.macro == :belongs_to
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::BelongsToReflections
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require_relative '../base/has_and_belongs_to_many_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasAndBelongsToManyReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_and_belongs_to_many_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
(reflection.macro == :has_and_belongs_to_many)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def has_and_belongs_to_many_ids klass_reflection
|
|
13
|
+
|
|
14
|
+
# First, we get the the join table
|
|
15
|
+
join_table = Arel::Table.new(klass_reflection.join_table)
|
|
16
|
+
|
|
17
|
+
# And now, the foreign_keys.
|
|
18
|
+
# In our example with BlogPost and Category they would be:
|
|
19
|
+
# model_foreign_key = blog_post_id
|
|
20
|
+
# related_model_foreign_key = category_id
|
|
21
|
+
model_foreign_key = klass_reflection.foreign_key
|
|
22
|
+
related_model_foreign_key = klass_reflection.association_foreign_key
|
|
23
|
+
|
|
24
|
+
# Now we query the join table so we get the two ids
|
|
25
|
+
ids_query = join_table.where(
|
|
26
|
+
join_table[model_foreign_key].in(@results.map{|_, r| r[:id] })
|
|
27
|
+
).project(
|
|
28
|
+
join_table[related_model_foreign_key],
|
|
29
|
+
join_table[model_foreign_key]
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
join_results = ActiveRecord::Base.connection.execute(ids_query.to_sql)
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
include Pluckers::Features::Base::HasAndBelongsToManyReflections
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative '../base/has_many_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasManyReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_many_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::AssociationReflection) &&
|
|
9
|
+
(reflection.macro == :has_many)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasManyReflections
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative '../base/has_many_through_reflections'
|
|
2
|
+
|
|
3
|
+
module Pluckers
|
|
4
|
+
module Features
|
|
5
|
+
module HasManyThroughReflections
|
|
6
|
+
|
|
7
|
+
def active_record_has_many_through_reflection? reflection
|
|
8
|
+
reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) &&
|
|
9
|
+
(reflection.macro == :has_many)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
include Pluckers::Features::Base::HasManyThroughReflections
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|