mongoid 9.0.3 → 9.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mongoid/attributes/readonly.rb +8 -3
- data/lib/mongoid/criteria/queryable/selectable.rb +1 -1
- data/lib/mongoid/equality.rb +1 -0
- data/lib/mongoid/loadable.rb +72 -8
- data/lib/mongoid/persistence_context.rb +1 -1
- data/lib/mongoid/traversable.rb +24 -5
- data/lib/mongoid/version.rb +1 -1
- data/spec/mongoid/attributes/readonly_spec.rb +19 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +29 -0
- data/spec/mongoid/equality_spec.rb +6 -0
- data/spec/mongoid/loadable_spec.rb +86 -0
- data/spec/mongoid/persistence_context_spec.rb +8 -0
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ac7ac8e60ba9d953a5a809d17b7fca7a2501988cdec50d12348af3b7022f615
|
4
|
+
data.tar.gz: 27a2bceb132e4f6b33d8be6b70ac8074b8de421c5c1efdb03f3ad2fc97d62364
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31cea6e77afe05358ff9cdaf5bc861807a93ce9c89e7cfd9209c0f35a2df816fb8d4d595faafbab2665b2dab776f523d0b96eece4b249626f976ec685765d5a5
|
7
|
+
data.tar.gz: 1367fb446dae452b73227c099e72ed2f13bd2702434e8050c09f3c1ae2ad97b5346371252ce3cfa3442151353bd8c8ef9a409cd2de75edb7cdf20ff3322107c7
|
@@ -23,7 +23,7 @@ module Mongoid
|
|
23
23
|
# @return [ true | false ] If the document is new, or if the field is not
|
24
24
|
# readonly.
|
25
25
|
def attribute_writable?(name)
|
26
|
-
new_record? || (!readonly_attributes.include?(name) && _loaded?(name))
|
26
|
+
new_record? || (!self.class.readonly_attributes.include?(name) && _loaded?(name))
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
@@ -63,12 +63,17 @@ module Mongoid
|
|
63
63
|
# end
|
64
64
|
#
|
65
65
|
# @param [ Symbol... ] *names The names of the fields.
|
66
|
+
# @note When a parent class contains readonly attributes and is then
|
67
|
+
# inherited by a child class, the child class will inherit the
|
68
|
+
# parent's readonly attributes at the time of its creation.
|
69
|
+
# Updating the parent does not propagate down to child classes after wards.
|
66
70
|
def attr_readonly(*names)
|
71
|
+
self.readonly_attributes = self.readonly_attributes.dup
|
67
72
|
names.each do |name|
|
68
|
-
readonly_attributes << database_field_name(name)
|
73
|
+
self.readonly_attributes << database_field_name(name)
|
69
74
|
end
|
70
75
|
end
|
71
76
|
end
|
72
77
|
end
|
73
78
|
end
|
74
|
-
end
|
79
|
+
end
|
@@ -553,7 +553,7 @@ module Mongoid
|
|
553
553
|
# @return [ Selectable ] The new selectable.
|
554
554
|
def not(*criteria)
|
555
555
|
if criteria.empty?
|
556
|
-
dup.tap { |query| query.negating =
|
556
|
+
dup.tap { |query| query.negating = !query.negating }
|
557
557
|
else
|
558
558
|
criteria.compact.inject(self.clone) do |c, new_s|
|
559
559
|
if new_s.is_a?(Selectable)
|
data/lib/mongoid/equality.rb
CHANGED
data/lib/mongoid/loadable.rb
CHANGED
@@ -10,6 +10,13 @@ module Mongoid
|
|
10
10
|
# (See #model_paths.)
|
11
11
|
DEFAULT_MODEL_PATHS = %w( ./app/models ./lib/models ).freeze
|
12
12
|
|
13
|
+
# The default list of glob patterns that match paths to ignore when loading
|
14
|
+
# models. Defaults to '*/models/concerns/*', which Rails uses for extensions
|
15
|
+
# to models (and which cause errors when loaded out of order).
|
16
|
+
#
|
17
|
+
# See #ignore_patterns.
|
18
|
+
DEFAULT_IGNORE_PATTERNS = %w( */models/concerns/* ).freeze
|
19
|
+
|
13
20
|
# Search a list of model paths to get every model and require it, so
|
14
21
|
# that indexing and inheritance work in both development and production
|
15
22
|
# with the same results.
|
@@ -24,17 +31,47 @@ module Mongoid
|
|
24
31
|
# for model files. These must either be absolute paths, or relative to
|
25
32
|
# the current working directory.
|
26
33
|
def load_models(paths = model_paths)
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
files = files_under_paths(paths)
|
35
|
+
|
36
|
+
files.sort.each do |file|
|
37
|
+
load_model(file)
|
38
|
+
end
|
39
|
+
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# Given a list of paths, return all ruby files under that path (or, if
|
44
|
+
# `preload_models` is a list of model names, returns only the files for
|
45
|
+
# those named models).
|
46
|
+
#
|
47
|
+
# @param [ Array<String> ] paths the list of paths to search
|
48
|
+
#
|
49
|
+
# @return [ Array<String> ] the normalized file names, suitable for loading
|
50
|
+
# via `require_dependency` or `require`.
|
51
|
+
def files_under_paths(paths)
|
52
|
+
paths.flat_map { |path| files_under_path(path) }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Given a single path, returns all ruby files under that path (or, if
|
56
|
+
# `preload_models` is a list of model names, returns only the files for
|
57
|
+
# those named models).
|
58
|
+
#
|
59
|
+
# @param [ String ] path the path to search
|
60
|
+
#
|
61
|
+
# @return [ Array<String> ] the normalized file names, suitable for loading
|
62
|
+
# via `require_dependency` or `require`.
|
63
|
+
def files_under_path(path)
|
64
|
+
files = if preload_models.resizable?
|
65
|
+
preload_models.
|
66
|
+
map { |model| "#{path}/#{model.underscore}.rb" }.
|
67
|
+
select { |file_name| File.exists?(file_name) }
|
30
68
|
else
|
31
|
-
|
69
|
+
Dir.glob("#{path}/**/*.rb").
|
70
|
+
reject { |file_name| ignored?(file_name) }
|
32
71
|
end
|
33
72
|
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
73
|
+
# strip the path and the suffix from each entry
|
74
|
+
files.map { |file| file.gsub(/^#{path}\// , "").gsub(/\.rb$/, "") }
|
38
75
|
end
|
39
76
|
|
40
77
|
# A convenience method for loading a model's file. If Rails'
|
@@ -71,6 +108,14 @@ module Mongoid
|
|
71
108
|
DEFAULT_MODEL_PATHS
|
72
109
|
end
|
73
110
|
|
111
|
+
# Returns the array of glob patterns that determine whether a given
|
112
|
+
# path should be ignored by the model loader.
|
113
|
+
#
|
114
|
+
# @return [ Array<String> ] the array of ignore patterns
|
115
|
+
def ignore_patterns
|
116
|
+
@ignore_patterns ||= DEFAULT_IGNORE_PATTERNS.dup
|
117
|
+
end
|
118
|
+
|
74
119
|
# Sets the model paths to the given array of paths. These are the paths
|
75
120
|
# where the application's model definitions are located.
|
76
121
|
#
|
@@ -78,6 +123,25 @@ module Mongoid
|
|
78
123
|
def model_paths=(paths)
|
79
124
|
@model_paths = paths
|
80
125
|
end
|
126
|
+
|
127
|
+
# Sets the ignore patterns to the given array of patterns. These are glob
|
128
|
+
# patterns that determine whether a given path should be ignored by the
|
129
|
+
# model loader or not.
|
130
|
+
#
|
131
|
+
# @param [ Array<String> ] patterns The list of glob patterns
|
132
|
+
def ignore_patterns=(patterns)
|
133
|
+
@ignore_patterns = patterns
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns true if the given file path matches any of the ignore patterns.
|
137
|
+
#
|
138
|
+
# @param [ String ] file_path The file path to consider
|
139
|
+
#
|
140
|
+
# @return [ true | false ] whether or not the given file path should be
|
141
|
+
# ignored.
|
142
|
+
def ignored?(file_path)
|
143
|
+
ignore_patterns.any? { |pattern| File.fnmatch?(pattern, file_path) }
|
144
|
+
end
|
81
145
|
end
|
82
146
|
|
83
147
|
end
|
@@ -138,7 +138,7 @@ module Mongoid
|
|
138
138
|
# @return [ Symbol ] The client name for this persistence
|
139
139
|
# context.
|
140
140
|
def client_name
|
141
|
-
@client_name ||= options[:client] ||
|
141
|
+
@client_name ||= __evaluate__(options[:client]) ||
|
142
142
|
Threaded.client_override ||
|
143
143
|
__evaluate__(storage_options[:client])
|
144
144
|
end
|
data/lib/mongoid/traversable.rb
CHANGED
@@ -8,6 +8,29 @@ module Mongoid
|
|
8
8
|
# around traversing the document graph.
|
9
9
|
module Traversable
|
10
10
|
extend ActiveSupport::Concern
|
11
|
+
# This code is extracted from ActiveSupport so that we do not depend on
|
12
|
+
# their private API that may change at any time.
|
13
|
+
# This code should be reviewed and maybe removed when implementing
|
14
|
+
# https://jira.mongodb.org/browse/MONGOID-5832
|
15
|
+
class << self
|
16
|
+
# @api private
|
17
|
+
def __redefine(owner, name, value)
|
18
|
+
if owner.singleton_class?
|
19
|
+
owner.redefine_method(name) { value }
|
20
|
+
owner.send(:public, name)
|
21
|
+
end
|
22
|
+
owner.redefine_singleton_method(name) { value }
|
23
|
+
owner.singleton_class.send(:public, name)
|
24
|
+
owner.redefine_singleton_method("#{name}=") do |new_value|
|
25
|
+
if owner.equal?(self)
|
26
|
+
value = new_value
|
27
|
+
else
|
28
|
+
::Mongoid::Traversable.redefine(self, name, new_value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
owner.singleton_class.send(:public, "#{name}=")
|
32
|
+
end
|
33
|
+
end
|
11
34
|
|
12
35
|
# Class-level methods for the Traversable behavior.
|
13
36
|
module ClassMethods
|
@@ -105,11 +128,7 @@ module Mongoid
|
|
105
128
|
if value
|
106
129
|
Mongoid::Fields::Validators::Macro.validate_field_name(self, value)
|
107
130
|
value = value.to_s
|
108
|
-
|
109
|
-
::ActiveSupport::ClassAttribute.redefine(self, 'discriminator_key', value)
|
110
|
-
else
|
111
|
-
super
|
112
|
-
end
|
131
|
+
::Mongoid::Traversable.__redefine(self, 'discriminator_key', value)
|
113
132
|
else
|
114
133
|
# When discriminator key is set to nil, replace the class's definition
|
115
134
|
# of the discriminator key reader (provided by class_attribute earlier)
|
data/lib/mongoid/version.rb
CHANGED
@@ -266,7 +266,26 @@ describe Mongoid::Attributes::Readonly do
|
|
266
266
|
expect(child.mother).to be_nil
|
267
267
|
end
|
268
268
|
end
|
269
|
+
end
|
270
|
+
|
271
|
+
context "when a subclass inherits readonly fields" do
|
272
|
+
let(:attributes) do
|
273
|
+
[:title, :terms]
|
274
|
+
end
|
275
|
+
|
276
|
+
before do
|
277
|
+
class OldPerson < Person
|
278
|
+
attr_readonly :age
|
279
|
+
end
|
280
|
+
end
|
269
281
|
|
282
|
+
it "ensures subclass inherits the readonly attributes from parent" do
|
283
|
+
expect(OldPerson.readonly_attributes.to_a).to include("title","terms")
|
284
|
+
end
|
285
|
+
|
286
|
+
it "ensures subclass does not modify parent's readonly attributes" do
|
287
|
+
expect(Person.readonly_attributes.to_a).not_to include("age")
|
288
|
+
end
|
270
289
|
end
|
271
290
|
end
|
272
291
|
end
|
@@ -1939,6 +1939,35 @@ describe Mongoid::Criteria::Queryable::Selectable do
|
|
1939
1939
|
end
|
1940
1940
|
end
|
1941
1941
|
|
1942
|
+
describe "#not" do
|
1943
|
+
context "when negating a criterion" do
|
1944
|
+
let(:selection) do
|
1945
|
+
query.not(field: /value/)
|
1946
|
+
end
|
1947
|
+
|
1948
|
+
it "adds the $not selector" do
|
1949
|
+
expect(selection.selector).to eq({
|
1950
|
+
"field" => { "$not" => /value/ }
|
1951
|
+
})
|
1952
|
+
end
|
1953
|
+
|
1954
|
+
it "returns a cloned query" do
|
1955
|
+
expect(selection).to_not equal(query)
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
context "when toggling negation state" do
|
1959
|
+
it "negates the negating value" do
|
1960
|
+
expect(query.negating).to be_nil
|
1961
|
+
negated_query = query.not
|
1962
|
+
expect(negated_query.negating).to be true
|
1963
|
+
double_negated_query = negated_query.not
|
1964
|
+
expect(double_negated_query.negating).to be false
|
1965
|
+
end
|
1966
|
+
end
|
1967
|
+
end
|
1968
|
+
end
|
1969
|
+
|
1970
|
+
|
1942
1971
|
describe Symbol do
|
1943
1972
|
|
1944
1973
|
describe "#all" do
|
@@ -189,6 +189,12 @@ describe Mongoid::Equality do
|
|
189
189
|
it "compares based on the document id" do
|
190
190
|
expect(first <=> second).to eq(-1)
|
191
191
|
end
|
192
|
+
|
193
|
+
it "doesn't break if one isn't a document" do
|
194
|
+
expect do
|
195
|
+
first <=> "Foo"
|
196
|
+
end.to_not raise_error
|
197
|
+
end
|
192
198
|
end
|
193
199
|
|
194
200
|
describe "#eql?" do
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Mongoid::Loadable do
|
6
|
+
let(:lib_dir) { Pathname.new('../../lib').realpath(__dir__) }
|
7
|
+
|
8
|
+
shared_context 'with ignore_patterns' do
|
9
|
+
around do |example|
|
10
|
+
saved = Mongoid.ignore_patterns
|
11
|
+
Mongoid.ignore_patterns = ignore_patterns
|
12
|
+
example.run
|
13
|
+
ensure
|
14
|
+
Mongoid.ignore_patterns = saved
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#ignore_patterns' do
|
19
|
+
context 'when not explicitly set' do
|
20
|
+
it 'equals the default list of ignore patterns' do
|
21
|
+
expect(Mongoid.ignore_patterns).to eq Mongoid::Loadable::DEFAULT_IGNORE_PATTERNS
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when explicitly set' do
|
26
|
+
include_context 'with ignore_patterns'
|
27
|
+
|
28
|
+
let(:ignore_patterns) { %w[ pattern1 pattern2 ] }
|
29
|
+
|
30
|
+
it 'equals the list of specified patterns' do
|
31
|
+
expect(Mongoid.ignore_patterns).to eq ignore_patterns
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#files_under_path' do
|
37
|
+
let(:results) { Mongoid.files_under_path(lib_dir) }
|
38
|
+
|
39
|
+
include_context 'with ignore_patterns'
|
40
|
+
|
41
|
+
context 'when ignore_patterns is empty' do
|
42
|
+
let(:ignore_patterns) { [] }
|
43
|
+
|
44
|
+
it 'returns all ruby files' do
|
45
|
+
expect(results.length).to be > 10 # should be a bunch of them
|
46
|
+
expect(results).to include('rails/mongoid')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when ignore_patterns is not empty' do
|
51
|
+
let(:ignore_patterns) { %w[ */rails/* ] }
|
52
|
+
|
53
|
+
it 'omits the ignored paths' do
|
54
|
+
expect(results.length).to be > 10 # should be a bunch of them
|
55
|
+
expect(results).not_to include('rails/mongoid')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#files_under_paths' do
|
61
|
+
let(:paths) { [ lib_dir.join('mongoid'), lib_dir.join('rails') ] }
|
62
|
+
let(:results) { Mongoid.files_under_paths(paths) }
|
63
|
+
|
64
|
+
include_context 'with ignore_patterns'
|
65
|
+
|
66
|
+
context 'when ignore_patterns is empty' do
|
67
|
+
let(:ignore_patterns) { [] }
|
68
|
+
|
69
|
+
it 'returns all ruby files' do
|
70
|
+
expect(results.length).to be > 10 # should be a bunch
|
71
|
+
expect(results).to include('generators/mongoid/model/model_generator')
|
72
|
+
expect(results).to include('fields/encrypted')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when ignore_patterns is not empty' do
|
77
|
+
let(:ignore_patterns) { %w[ */model/* */fields/* ] }
|
78
|
+
|
79
|
+
it 'returns all ruby files' do
|
80
|
+
expect(results.length).to be > 10 # should be a bunch
|
81
|
+
expect(results).not_to include('generators/mongoid/model/model_generator')
|
82
|
+
expect(results).not_to include('fields/encrypted')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -584,6 +584,14 @@ describe Mongoid::PersistenceContext do
|
|
584
584
|
expect(persistence_context.client).to eq(Mongoid::Clients.with_name(:alternative))
|
585
585
|
end
|
586
586
|
|
587
|
+
context 'when the client option is a proc' do
|
588
|
+
let(:options) { { client: -> { :alternative } } }
|
589
|
+
|
590
|
+
it 'evaluates the proc' do
|
591
|
+
expect(persistence_context.client).to eq(Mongoid::Clients.with_name(:alternative))
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
587
595
|
context 'when there is a client override' do
|
588
596
|
persistence_context_override :client, :other
|
589
597
|
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.0.
|
4
|
+
version: 9.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The MongoDB Ruby Team
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-01-08 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activemodel
|
@@ -830,6 +829,7 @@ files:
|
|
830
829
|
- spec/mongoid/inspectable_spec.rb
|
831
830
|
- spec/mongoid/interceptable_spec.rb
|
832
831
|
- spec/mongoid/interceptable_spec_models.rb
|
832
|
+
- spec/mongoid/loadable_spec.rb
|
833
833
|
- spec/mongoid/loading_spec.rb
|
834
834
|
- spec/mongoid/loggable_spec.rb
|
835
835
|
- spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml
|
@@ -1188,7 +1188,6 @@ metadata:
|
|
1188
1188
|
documentation_uri: https://www.mongodb.com/docs/mongoid/
|
1189
1189
|
homepage_uri: https://mongoid.org/
|
1190
1190
|
source_code_uri: https://github.com/mongodb/mongoid
|
1191
|
-
post_install_message:
|
1192
1191
|
rdoc_options: []
|
1193
1192
|
require_paths:
|
1194
1193
|
- lib
|
@@ -1203,8 +1202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1203
1202
|
- !ruby/object:Gem::Version
|
1204
1203
|
version: 1.3.6
|
1205
1204
|
requirements: []
|
1206
|
-
rubygems_version: 3.
|
1207
|
-
signing_key:
|
1205
|
+
rubygems_version: 3.6.2
|
1208
1206
|
specification_version: 4
|
1209
1207
|
summary: Elegant Persistence in Ruby for MongoDB.
|
1210
1208
|
test_files:
|
@@ -1552,6 +1550,7 @@ test_files:
|
|
1552
1550
|
- spec/mongoid/inspectable_spec.rb
|
1553
1551
|
- spec/mongoid/interceptable_spec.rb
|
1554
1552
|
- spec/mongoid/interceptable_spec_models.rb
|
1553
|
+
- spec/mongoid/loadable_spec.rb
|
1555
1554
|
- spec/mongoid/loading_spec.rb
|
1556
1555
|
- spec/mongoid/loggable_spec.rb
|
1557
1556
|
- spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml
|