mongoid 5.0.2 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|