pluckers 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|