mongoid 5.0.2 → 5.1.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/lib/mongoid/changeable.rb +1 -1
- data/lib/mongoid/clients.rb +1 -0
- data/lib/mongoid/clients/options.rb +119 -7
- data/lib/mongoid/config.rb +7 -0
- data/lib/mongoid/config/options.rb +15 -0
- data/lib/mongoid/contextual/geo_near.rb +12 -0
- data/lib/mongoid/contextual/mongo.rb +6 -0
- data/lib/mongoid/criteria.rb +2 -56
- data/lib/mongoid/criteria/findable.rb +4 -1
- data/lib/mongoid/criteria/includable.rb +142 -0
- data/lib/mongoid/criteria/modifiable.rb +13 -1
- data/lib/mongoid/document.rb +21 -0
- data/lib/mongoid/fields/foreign_key.rb +5 -1
- data/lib/mongoid/fields/localized.rb +16 -1
- data/lib/mongoid/fields/validators/macro.rb +1 -0
- data/lib/mongoid/findable.rb +1 -0
- data/lib/mongoid/loggable.rb +1 -1
- data/lib/mongoid/matchable.rb +6 -1
- data/lib/mongoid/persistable.rb +2 -2
- data/lib/mongoid/relations/eager.rb +12 -5
- data/lib/mongoid/relations/eager/base.rb +3 -1
- data/lib/mongoid/relations/referenced/many.rb +39 -6
- data/lib/mongoid/relations/targets/enumerable.rb +3 -3
- data/lib/mongoid/scopable.rb +5 -2
- data/lib/mongoid/version.rb +1 -1
- data/spec/app/models/address.rb +2 -0
- data/spec/app/models/agent.rb +2 -0
- data/spec/app/models/alert.rb +2 -0
- data/spec/app/models/post.rb +1 -0
- data/spec/config/mongoid.yml +1 -0
- data/spec/mongoid/changeable_spec.rb +1 -1
- data/spec/mongoid/clients/options_spec.rb +57 -0
- data/spec/mongoid/config_spec.rb +38 -0
- data/spec/mongoid/contextual/geo_near_spec.rb +19 -0
- data/spec/mongoid/criteria/findable_spec.rb +11 -0
- data/spec/mongoid/criteria/modifiable_spec.rb +126 -0
- data/spec/mongoid/criteria_spec.rb +81 -5
- data/spec/mongoid/document_spec.rb +56 -0
- data/spec/mongoid/fields/foreign_key_spec.rb +23 -0
- data/spec/mongoid/fields/localized_spec.rb +32 -14
- data/spec/mongoid/matchable_spec.rb +127 -1
- data/spec/mongoid/persistable_spec.rb +24 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +16 -0
- data/spec/mongoid/relations/referenced/many_spec.rb +60 -0
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +40 -0
- data/spec/mongoid/scopable_spec.rb +67 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/authorization.rb +2 -1
- metadata +6 -5
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d93faa3fdc0513cf6d8daafdf1ab90fd4744fd8
|
4
|
+
data.tar.gz: 77316de1b6bdd99154eacba90bd510b2ca636fdb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9397767bc7a5cfb49438682bea971816f69a6053beb740cc2ab17fec5add3e59f08d72958464b762d3ad399612479b99810b629969ca184c1bebc65fb661c1b2
|
7
|
+
data.tar.gz: 0725f14ab25f26b0bc29e73b721d9bfe84de5a83119a7fd390957ef4c81c90d8a270725bb42d56b7f3e782cf059e9292815ba8c683585d80ba813ed20e20f809
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -31,7 +31,7 @@ Please see the [MongoDB website](http://docs.mongodb.org/ecosystem/tutorial/ruby
|
|
31
31
|
License
|
32
32
|
-------
|
33
33
|
|
34
|
-
Copyright (c) 2009-
|
34
|
+
Copyright (c) 2009-2016 Durran Jordan
|
35
35
|
|
36
36
|
Permission is hereby granted, free of charge, to any person obtaining
|
37
37
|
a copy of this software and associated documentation files (the
|
data/lib/mongoid/changeable.rb
CHANGED
data/lib/mongoid/clients.rb
CHANGED
@@ -111,6 +111,7 @@ module Mongoid
|
|
111
111
|
#
|
112
112
|
# @since 3.0.0
|
113
113
|
def mongo_client
|
114
|
+
return client_with_options if client_with_options
|
114
115
|
client = Clients.with_name(client_name)
|
115
116
|
opts = self.persistence_options ? self.persistence_options.dup : {}
|
116
117
|
if defined?(Mongo::Client::VALID_OPTIONS)
|
@@ -43,14 +43,15 @@ module Mongoid
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def mongo_client
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
tmp = persistence_options
|
47
|
+
if opts = tmp && tmp.dup
|
48
|
+
if opts[:client]
|
49
|
+
client = Clients.with_name(opts[:client])
|
49
50
|
else
|
50
51
|
client = Clients.with_name(self.class.client_name)
|
51
52
|
client.use(self.class.database_name)
|
52
53
|
end
|
53
|
-
client.with(
|
54
|
+
client.with(opts.reject{ |k, v| k == :collection || k == :client })
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
@@ -76,13 +77,27 @@ module Mongoid
|
|
76
77
|
Thread.current["[mongoid][#{klass}]:persistence-options"]
|
77
78
|
end
|
78
79
|
|
80
|
+
# Get the client with special options for the current thread.
|
81
|
+
#
|
82
|
+
# @example Get the client with options.
|
83
|
+
# Threaded.client_with_options(Band)
|
84
|
+
#
|
85
|
+
# @param [ Class ] klass The model class.
|
86
|
+
#
|
87
|
+
# @return [ Mongo::Client ] The client.
|
88
|
+
#
|
89
|
+
# @since 5.1.0
|
90
|
+
def client_with_options(klass = self)
|
91
|
+
Thread.current["[mongoid][#{klass}]:mongo-client"]
|
92
|
+
end
|
93
|
+
|
79
94
|
private
|
80
95
|
# Set the persistence options on the current thread.
|
81
96
|
#
|
82
97
|
# @api private
|
83
98
|
#
|
84
99
|
# @example Set the persistence options.
|
85
|
-
# Threaded.set_persistence_options(Band, {
|
100
|
+
# Threaded.set_persistence_options(Band, { write: { w: 3 }})
|
86
101
|
#
|
87
102
|
# @param [ Class ] klass The model class.
|
88
103
|
# @param [ Hash ] options The persistence options.
|
@@ -93,6 +108,97 @@ module Mongoid
|
|
93
108
|
def set_persistence_options(klass, options)
|
94
109
|
Thread.current["[mongoid][#{klass}]:persistence-options"] = options
|
95
110
|
end
|
111
|
+
|
112
|
+
# Unset the persistence options on the current thread.
|
113
|
+
#
|
114
|
+
# @api private
|
115
|
+
#
|
116
|
+
# @example Unset the persistence options.
|
117
|
+
# Threaded.unset_persistence_options(Band)
|
118
|
+
#
|
119
|
+
# @param [ Class ] klass The model class.
|
120
|
+
#
|
121
|
+
# @return [ nil ] nil.
|
122
|
+
#
|
123
|
+
# @since 5.1.0
|
124
|
+
def unset_persistence_options(klass)
|
125
|
+
Thread.current["[mongoid][#{klass}]:persistence-options"] = nil
|
126
|
+
end
|
127
|
+
|
128
|
+
# Set the persistence options and client with those options on the current thread.
|
129
|
+
# Note that a client will only be set if its cluster differs from the cluster of the
|
130
|
+
# original client.
|
131
|
+
#
|
132
|
+
# @api private
|
133
|
+
#
|
134
|
+
# @example Set the persistence options and client with those options on the current thread.
|
135
|
+
# Threaded.set_options(Band, { write: { w: 3 }})
|
136
|
+
#
|
137
|
+
# @param [ Class ] klass The model class.
|
138
|
+
# @param [ Mongo::Client ] client The client with options.
|
139
|
+
#
|
140
|
+
# @return [ Mongo::Client, nil ] The client or nil if the cluster does not change.
|
141
|
+
#
|
142
|
+
# @since 5.1.0
|
143
|
+
def set_options(klass, options)
|
144
|
+
original_cluster = mongo_client.cluster
|
145
|
+
set_persistence_options(klass, options)
|
146
|
+
m = mongo_client
|
147
|
+
set_client_with_options(klass, m) unless m.cluster.equal?(original_cluster)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Set the client with special options on the current thread.
|
151
|
+
#
|
152
|
+
# @api private
|
153
|
+
#
|
154
|
+
# @example Set the client with options.
|
155
|
+
# Threaded.set_client_with_options(Band, client)
|
156
|
+
#
|
157
|
+
# @param [ Class ] klass The model class.
|
158
|
+
# @param [ Mongo::Client ] client The client with options.
|
159
|
+
#
|
160
|
+
# @return [ Mongo::Client ] The client.
|
161
|
+
#
|
162
|
+
# @since 5.1.0
|
163
|
+
def set_client_with_options(klass, client)
|
164
|
+
Thread.current["[mongoid][#{klass}]:mongo-client"] = client
|
165
|
+
end
|
166
|
+
|
167
|
+
# Unset the client with special options on the current thread.
|
168
|
+
#
|
169
|
+
# @api private
|
170
|
+
#
|
171
|
+
# @example Unset the client with options.
|
172
|
+
# Threaded.unset_client_with_options(Band)
|
173
|
+
#
|
174
|
+
# @param [ Class ] klass The model class.
|
175
|
+
#
|
176
|
+
# @return [ nil ] nil.
|
177
|
+
#
|
178
|
+
# @since 5.1.0
|
179
|
+
def unset_client_with_options(klass)
|
180
|
+
if client = Thread.current["[mongoid][#{klass}]:mongo-client"]
|
181
|
+
client.close
|
182
|
+
Thread.current["[mongoid][#{klass}]:mongo-client"] = nil
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# Unset the persistence options and client with special options on the current thread.
|
187
|
+
#
|
188
|
+
# @api private
|
189
|
+
#
|
190
|
+
# @example Unset the persistence options and client with options.
|
191
|
+
# Threaded.unset_options(Band)
|
192
|
+
#
|
193
|
+
# @param [ Class ] klass The model class.
|
194
|
+
#
|
195
|
+
# @return [ nil ] nil.
|
196
|
+
#
|
197
|
+
# @since 5.1.0
|
198
|
+
def unset_options(klass)
|
199
|
+
unset_persistence_options(klass)
|
200
|
+
unset_client_with_options(klass)
|
201
|
+
end
|
96
202
|
end
|
97
203
|
|
98
204
|
module ClassMethods
|
@@ -144,7 +250,13 @@ module Mongoid
|
|
144
250
|
#
|
145
251
|
# @since 3.0.0
|
146
252
|
def with(options)
|
147
|
-
|
253
|
+
if block_given?
|
254
|
+
set_options(self, options)
|
255
|
+
yield self
|
256
|
+
unset_options(self)
|
257
|
+
else
|
258
|
+
Proxy.new(self, (persistence_options || {}).merge(options))
|
259
|
+
end
|
148
260
|
end
|
149
261
|
end
|
150
262
|
|
@@ -174,7 +286,7 @@ module Mongoid
|
|
174
286
|
end
|
175
287
|
ret
|
176
288
|
ensure
|
177
|
-
|
289
|
+
unset_persistence_options(@target)
|
178
290
|
end
|
179
291
|
|
180
292
|
def send(symbol, *args)
|
data/lib/mongoid/config.rb
CHANGED
@@ -24,6 +24,7 @@ module Mongoid
|
|
24
24
|
option :duplicate_fields_exception, default: false
|
25
25
|
option :use_activesupport_time_zone, default: true
|
26
26
|
option :use_utc, default: false
|
27
|
+
option :log_level, default: :info
|
27
28
|
|
28
29
|
# Has Mongoid been configured? This is checking that at least a valid
|
29
30
|
# client config exists.
|
@@ -128,6 +129,7 @@ module Mongoid
|
|
128
129
|
configuration = settings.with_indifferent_access
|
129
130
|
self.options = configuration[:options]
|
130
131
|
self.clients = configuration[:clients]
|
132
|
+
set_log_levels
|
131
133
|
end
|
132
134
|
|
133
135
|
# Override the database to use globally.
|
@@ -243,6 +245,11 @@ module Mongoid
|
|
243
245
|
|
244
246
|
private
|
245
247
|
|
248
|
+
def set_log_levels
|
249
|
+
Mongoid.logger.level = Mongoid::Config.log_level
|
250
|
+
Mongo::Logger.logger.level = Mongoid.logger.level
|
251
|
+
end
|
252
|
+
|
246
253
|
def clients=(clients)
|
247
254
|
raise Errors::NoClientsConfig.new unless clients
|
248
255
|
c = clients.with_indifferent_access
|
@@ -69,6 +69,21 @@ module Mongoid
|
|
69
69
|
def settings
|
70
70
|
@settings ||= {}
|
71
71
|
end
|
72
|
+
|
73
|
+
# Get the log level.
|
74
|
+
#
|
75
|
+
# @example Get the log level.
|
76
|
+
# config.log_level
|
77
|
+
#
|
78
|
+
# @return [ Integer ] The log level.
|
79
|
+
#
|
80
|
+
# @since 5.1.0
|
81
|
+
def log_level
|
82
|
+
if settings[:log_level]
|
83
|
+
level = settings[:log_level].upcase.to_s
|
84
|
+
"Logger::#{level}".constantize
|
85
|
+
end
|
86
|
+
end
|
72
87
|
end
|
73
88
|
end
|
74
89
|
end
|
@@ -198,6 +198,18 @@ module Mongoid
|
|
198
198
|
stats["time"]
|
199
199
|
end
|
200
200
|
|
201
|
+
# Is this context's criteria considered empty?
|
202
|
+
#
|
203
|
+
# @example Is this context's criteria considered empty?
|
204
|
+
# geo_near.empty_and_chainable?
|
205
|
+
#
|
206
|
+
# @return [ true ] Always true.
|
207
|
+
#
|
208
|
+
# @since 5.1.0
|
209
|
+
def empty_and_chainable?
|
210
|
+
true
|
211
|
+
end
|
212
|
+
|
201
213
|
private
|
202
214
|
|
203
215
|
# Apply criteria specific options - query, limit.
|
@@ -543,6 +543,12 @@ module Mongoid
|
|
543
543
|
if criteria.options[:timeout] == false
|
544
544
|
@view = view.no_cursor_timeout
|
545
545
|
end
|
546
|
+
if criteria.options[:cursor_type]
|
547
|
+
# @todo: update to use #cursor_type method on view when driver 2.3 is released.
|
548
|
+
# See RUBY-1080
|
549
|
+
@view = view.clone
|
550
|
+
@view.options.merge!(cursor_type: criteria.options[:cursor_type])
|
551
|
+
end
|
546
552
|
end
|
547
553
|
|
548
554
|
# Apply an option.
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "mongoid/criteria/findable"
|
3
|
+
require "mongoid/criteria/includable"
|
3
4
|
require "mongoid/criteria/inspectable"
|
4
5
|
require "mongoid/criteria/marshalable"
|
5
6
|
require "mongoid/criteria/modifiable"
|
@@ -19,6 +20,7 @@ module Mongoid
|
|
19
20
|
include Origin::Queryable
|
20
21
|
include Findable
|
21
22
|
include Inspectable
|
23
|
+
include Includable
|
22
24
|
include Marshalable
|
23
25
|
include Modifiable
|
24
26
|
include Scopable
|
@@ -194,62 +196,6 @@ module Mongoid
|
|
194
196
|
klass ? super(klass.aliased_fields, klass.fields) : super({}, {})
|
195
197
|
end
|
196
198
|
|
197
|
-
# Eager loads all the provided relations. Will load all the documents
|
198
|
-
# into the identity map whose ids match based on the extra query for the
|
199
|
-
# ids.
|
200
|
-
#
|
201
|
-
# @note This will work for embedded relations that reference another
|
202
|
-
# collection via belongs_to as well.
|
203
|
-
#
|
204
|
-
# @note Eager loading brings all the documents into memory, so there is a
|
205
|
-
# sweet spot on the performance gains. Internal benchmarks show that
|
206
|
-
# eager loading becomes slower around 100k documents, but this will
|
207
|
-
# naturally depend on the specific application.
|
208
|
-
#
|
209
|
-
# @example Eager load the provided relations.
|
210
|
-
# Person.includes(:posts, :game)
|
211
|
-
#
|
212
|
-
# @param [ Array<Symbol> ] relations The names of the relations to eager
|
213
|
-
# load.
|
214
|
-
#
|
215
|
-
# @return [ Criteria ] The cloned criteria.
|
216
|
-
#
|
217
|
-
# @since 2.2.0
|
218
|
-
def includes(*relations)
|
219
|
-
relations.flatten.each do |name|
|
220
|
-
metadata = klass.reflect_on_association(name)
|
221
|
-
raise Errors::InvalidIncludes.new(klass, relations) unless metadata
|
222
|
-
inclusions.push(metadata) unless inclusions.include?(metadata)
|
223
|
-
end
|
224
|
-
clone
|
225
|
-
end
|
226
|
-
|
227
|
-
# Get a list of criteria that are to be executed for eager loading.
|
228
|
-
#
|
229
|
-
# @example Get the eager loading inclusions.
|
230
|
-
# Person.includes(:game).inclusions
|
231
|
-
#
|
232
|
-
# @return [ Array<Metadata> ] The inclusions.
|
233
|
-
#
|
234
|
-
# @since 2.2.0
|
235
|
-
def inclusions
|
236
|
-
@inclusions ||= []
|
237
|
-
end
|
238
|
-
|
239
|
-
# Set the inclusions for the criteria.
|
240
|
-
#
|
241
|
-
# @example Set the inclusions.
|
242
|
-
# criteria.inclusions = [ meta ]
|
243
|
-
#
|
244
|
-
# @param [ Array<Metadata> ] The inclusions.
|
245
|
-
#
|
246
|
-
# @return [ Array<Metadata> ] The new inclusions.
|
247
|
-
#
|
248
|
-
# @since 3.0.0
|
249
|
-
def inclusions=(value)
|
250
|
-
@inclusions = value
|
251
|
-
end
|
252
|
-
|
253
199
|
# Merges another object with this +Criteria+ and returns a new criteria.
|
254
200
|
# The other object may be a +Criteria+ or a +Hash+. This is used to
|
255
201
|
# combine multiple scopes together, where a chained scope situation
|
@@ -120,7 +120,10 @@ module Mongoid
|
|
120
120
|
#
|
121
121
|
# @since 3.0.0
|
122
122
|
def mongoize_ids(ids)
|
123
|
-
ids.map
|
123
|
+
ids.map do |id|
|
124
|
+
id = id[:id] if id.respond_to?(:keys) && id[:id]
|
125
|
+
klass.fields["_id"].mongoize(id)
|
126
|
+
end
|
124
127
|
end
|
125
128
|
|
126
129
|
# Convenience method of raising an invalid options error.
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
class Criteria
|
4
|
+
|
5
|
+
# Module providing functionality for parsing (nested) inclusion definitions.
|
6
|
+
module Includable
|
7
|
+
|
8
|
+
# Eager loads all the provided relations. Will load all the documents
|
9
|
+
# into the identity map whose ids match based on the extra query for the
|
10
|
+
# ids.
|
11
|
+
#
|
12
|
+
# @note This will work for embedded relations that reference another
|
13
|
+
# collection via belongs_to as well.
|
14
|
+
#
|
15
|
+
# @note Eager loading brings all the documents into memory, so there is a
|
16
|
+
# sweet spot on the performance gains. Internal benchmarks show that
|
17
|
+
# eager loading becomes slower around 100k documents, but this will
|
18
|
+
# naturally depend on the specific application.
|
19
|
+
#
|
20
|
+
# @example Eager load the provided relations.
|
21
|
+
# Person.includes(:posts, :game)
|
22
|
+
#
|
23
|
+
# @param [ Array<Symbol>, Array<Hash> ] relations The names of the relations to eager
|
24
|
+
# load.
|
25
|
+
#
|
26
|
+
# @return [ Criteria ] The cloned criteria.
|
27
|
+
#
|
28
|
+
# @since 2.2.0
|
29
|
+
def includes(*relations)
|
30
|
+
relations.flatten.each do |relation|
|
31
|
+
if relation.is_a?(Hash)
|
32
|
+
extract_nested_inclusion(klass, relation)
|
33
|
+
else
|
34
|
+
add_inclusion(klass, relation)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
clone
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get a list of criteria that are to be executed for eager loading.
|
41
|
+
#
|
42
|
+
# @example Get the eager loading inclusions.
|
43
|
+
# Person.includes(:game).inclusions
|
44
|
+
#
|
45
|
+
# @return [ Array<Metadata> ] The inclusions.
|
46
|
+
#
|
47
|
+
# @since 2.2.0
|
48
|
+
def inclusions
|
49
|
+
@inclusions ||= []
|
50
|
+
end
|
51
|
+
|
52
|
+
# Set the inclusions for the criteria.
|
53
|
+
#
|
54
|
+
# @example Set the inclusions.
|
55
|
+
# criteria.inclusions = [ meta ]
|
56
|
+
#
|
57
|
+
# @param [ Array<Metadata> ] The inclusions.
|
58
|
+
#
|
59
|
+
# @return [ Array<Metadata> ] The new inclusions.
|
60
|
+
#
|
61
|
+
# @since 3.0.0
|
62
|
+
def inclusions=(value)
|
63
|
+
@inclusions = value
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Add an inclusion definition to the list of inclusions for the criteria.
|
69
|
+
#
|
70
|
+
# @example Add an inclusion.
|
71
|
+
# criteria.add_inclusion(Person, :posts)
|
72
|
+
#
|
73
|
+
# @param [ Class, String, Symbol ] _klass The class or string/symbol of the class name.
|
74
|
+
# @param [ Symbol ] relation The relation.
|
75
|
+
#
|
76
|
+
# @raise [ Errors::InvalidIncludes ] If no relation is found.
|
77
|
+
#
|
78
|
+
# @since 5.1.0
|
79
|
+
def add_inclusion(_klass, relation)
|
80
|
+
metadata = get_inclusion_metadata(_klass, relation)
|
81
|
+
raise Errors::InvalidIncludes.new(_klass, [ relation ]) unless metadata
|
82
|
+
inclusions.push(metadata) unless inclusions.include?(metadata)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Extract inclusion definitions from a list.
|
86
|
+
#
|
87
|
+
# @example Extract the inclusions from a list.
|
88
|
+
# criteria.extract_relations_list(:posts, [{ :alerts => :items }])
|
89
|
+
#
|
90
|
+
# @param [ Symbol ] association The name of the association.
|
91
|
+
# @param [ Array ] relations A list of associations.
|
92
|
+
#
|
93
|
+
# @since 5.1.0
|
94
|
+
def extract_relations_list(association, relations)
|
95
|
+
relations.each do |relation|
|
96
|
+
if relation.is_a?(Hash)
|
97
|
+
extract_nested_inclusion(association, relation)
|
98
|
+
else
|
99
|
+
add_inclusion(association, relation)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Extract nested inclusion.
|
105
|
+
#
|
106
|
+
# @example Extract the inclusions from a nested definition.
|
107
|
+
# criteria.extract_nested_inclusion(User, { :posts => [:alerts] })
|
108
|
+
#
|
109
|
+
# @param [ Class, Symbol ] _klass The class for which the inclusion should be added.
|
110
|
+
# @param [ Hash ] relation The nested inclusion.
|
111
|
+
#
|
112
|
+
# @since 5.1.0
|
113
|
+
def extract_nested_inclusion(_klass, relation)
|
114
|
+
relation.each do |association, _inclusion|
|
115
|
+
add_inclusion(_klass, association)
|
116
|
+
if _inclusion.is_a?(Array)
|
117
|
+
extract_relations_list(association, _inclusion)
|
118
|
+
else
|
119
|
+
add_inclusion(association, _inclusion)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Get the metadata for an inclusion.
|
125
|
+
#
|
126
|
+
# @example Get the metadata for an inclusion definition.
|
127
|
+
# criteria.get_inclusion_metadata(User, :posts)
|
128
|
+
#
|
129
|
+
# @param [ Class, Symbol, String ] _klass The class for determining the association metadata
|
130
|
+
# @param [ Symbol ] association The name of the association.
|
131
|
+
#
|
132
|
+
# @since 5.1.0
|
133
|
+
def get_inclusion_metadata(_klass, association)
|
134
|
+
if _klass.is_a?(Class)
|
135
|
+
_klass.reflect_on_association(association)
|
136
|
+
else
|
137
|
+
_klass.to_s.classify.constantize.reflect_on_association(association)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|