mongoid 9.0.3 → 9.0.4
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
- 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
|