mongoid 7.1.0 → 7.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +6 -6
  5. data/README.md +1 -1
  6. data/lib/config/locales/en.yml +4 -4
  7. data/lib/mongoid/association/referenced/belongs_to/eager.rb +38 -2
  8. data/lib/mongoid/association/referenced/eager.rb +29 -9
  9. data/lib/mongoid/config.rb +39 -9
  10. data/lib/mongoid/criteria.rb +16 -3
  11. data/lib/mongoid/criteria/queryable/pipeline.rb +3 -2
  12. data/lib/mongoid/criteria/queryable/selectable.rb +94 -7
  13. data/lib/mongoid/criteria/queryable/storable.rb +104 -99
  14. data/lib/mongoid/errors/eager_load.rb +2 -0
  15. data/lib/mongoid/persistable/pushable.rb +7 -1
  16. data/lib/mongoid/serializable.rb +9 -3
  17. data/lib/mongoid/version.rb +1 -1
  18. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +32 -23
  19. data/spec/app/models/coding.rb +4 -0
  20. data/spec/app/models/coding/pull_request.rb +12 -0
  21. data/spec/app/models/delegating_patient.rb +16 -0
  22. data/spec/app/models/publication.rb +5 -0
  23. data/spec/app/models/publication/encyclopedia.rb +12 -0
  24. data/spec/app/models/publication/review.rb +14 -0
  25. data/spec/integration/document_spec.rb +22 -0
  26. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +193 -10
  27. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +504 -127
  28. data/spec/mongoid/criteria/queryable/selectable_spec.rb +52 -0
  29. data/spec/mongoid/criteria/queryable/storable_spec.rb +80 -2
  30. data/spec/mongoid/criteria_spec.rb +32 -0
  31. data/spec/mongoid/persistable/pushable_spec.rb +55 -1
  32. data/spec/mongoid/serializable_spec.rb +129 -18
  33. data/spec/spec_helper.rb +2 -0
  34. data/spec/support/expectations.rb +3 -1
  35. data/spec/support/helpers.rb +11 -0
  36. metadata +504 -490
  37. metadata.gz.sig +0 -0
@@ -2450,6 +2450,58 @@ describe Mongoid::Criteria::Queryable::Selectable do
2450
2450
  end
2451
2451
  end
2452
2452
  end
2453
+
2454
+ context 'when using an MQL logical operator manually' do
2455
+ let(:base_query) do
2456
+ query.where(test: 1)
2457
+ end
2458
+
2459
+ let(:selection) do
2460
+ base_query.where(mql_operator => ['hello' => 'world'])
2461
+ end
2462
+
2463
+ shared_examples_for 'adds conditions to existing query' do
2464
+ it 'adds conditions to existing query' do
2465
+ selection.selector.should == {
2466
+ 'test' => 1,
2467
+ mql_operator => ['hello' => 'world'],
2468
+ }
2469
+ end
2470
+ end
2471
+
2472
+ shared_examples_for 'adds conditions to existing query with an extra $and' do
2473
+ it 'adds conditions to existing query' do
2474
+ selection.selector.should == {
2475
+ 'test' => 1,
2476
+ mql_operator => ['hello' => 'world'],
2477
+ }
2478
+ end
2479
+ end
2480
+
2481
+ context '$or' do
2482
+ let(:mql_operator) { '$or' }
2483
+
2484
+ it_behaves_like 'adds conditions to existing query with an extra $and'
2485
+ end
2486
+
2487
+ context '$nor' do
2488
+ let(:mql_operator) { '$nor' }
2489
+
2490
+ it_behaves_like 'adds conditions to existing query with an extra $and'
2491
+ end
2492
+
2493
+ context '$not' do
2494
+ let(:mql_operator) { '$not' }
2495
+
2496
+ it_behaves_like 'adds conditions to existing query'
2497
+ end
2498
+
2499
+ context '$and' do
2500
+ let(:mql_operator) { '$and' }
2501
+
2502
+ it_behaves_like 'adds conditions to existing query'
2503
+ end
2504
+ end
2453
2505
  end
2454
2506
 
2455
2507
  describe Symbol do
@@ -52,6 +52,22 @@ describe Mongoid::Criteria::Queryable::Storable do
52
52
  end
53
53
  end
54
54
 
55
+ context '$and to query with $and which already has the given key' do
56
+ let(:query) do
57
+ Mongoid::Query.new.where('$and' => [{foo: 'zoom'}])
58
+ end
59
+
60
+ let(:modified) do
61
+ query.send(query_method, '$and', [{'foo' => 'bar'}])
62
+ end
63
+
64
+ it 'adds to existing $and' do
65
+ modified.selector.should == {
66
+ '$and' => [{'foo' => 'zoom'}, {'foo' => 'bar'}],
67
+ }
68
+ end
69
+ end
70
+
55
71
  end
56
72
 
57
73
  context '$or operator' do
@@ -74,9 +90,11 @@ describe Mongoid::Criteria::Queryable::Storable do
74
90
  query.send(query_method, '$or', [{'foo' => 'bar'}])
75
91
  end
76
92
 
77
- it 'replaces top level' do
93
+ it 'adds the new conditions' do
78
94
  modified.selector.should == {
79
- '$or' => [{'zoom' => 'zoom'}, {'foo' => 'bar'}]}
95
+ 'zoom' => 'zoom',
96
+ '$or' => ['foo' => 'bar'],
97
+ }
80
98
  end
81
99
  end
82
100
 
@@ -98,6 +116,66 @@ describe Mongoid::Criteria::Queryable::Storable do
98
116
  end
99
117
  end
100
118
 
119
+ describe '#add_field_expression' do
120
+ context 'simple field and value write' do
121
+ let(:modified) do
122
+ query.add_field_expression('foo', 'bar')
123
+ end
124
+
125
+ it 'adds the condition' do
126
+ modified.selector.should == {
127
+ 'foo' => 'bar'
128
+ }
129
+ end
130
+ end
131
+
132
+ context 'an operator write' do
133
+ let(:modified) do
134
+ query.add_field_expression('$eq', {'foo' => 'bar'})
135
+ end
136
+
137
+ it 'is not allowed' do
138
+ lambda do
139
+ modified
140
+ end.should raise_error(ArgumentError, /Field cannot be an operator/)
141
+ end
142
+ end
143
+
144
+ context 'when another field exists in destination' do
145
+ let(:base) do
146
+ query.add_field_expression('foo', 'bar')
147
+ end
148
+
149
+ let(:modified) do
150
+ base.add_field_expression('zoom', 'zoom')
151
+ end
152
+
153
+ it 'adds the condition' do
154
+ modified.selector.should == {
155
+ 'foo' => 'bar',
156
+ 'zoom' => 'zoom',
157
+ }
158
+ end
159
+ end
160
+
161
+ context 'when field being added already exists in destination' do
162
+ let(:base) do
163
+ query.add_field_expression('foo', 'bar')
164
+ end
165
+
166
+ let(:modified) do
167
+ base.add_field_expression('foo', 'zoom')
168
+ end
169
+
170
+ it 'adds the new condition using $and' do
171
+ modified.selector.should == {
172
+ 'foo' => 'bar',
173
+ '$and' => ['foo' => 'zoom'],
174
+ }
175
+ end
176
+ end
177
+ end
178
+
101
179
  describe '#add_operator_expression' do
102
180
  let(:query_method) { :add_operator_expression }
103
181
 
@@ -3428,6 +3428,38 @@ describe Mongoid::Criteria do
3428
3428
  Band.create(name: "Tool")
3429
3429
  end
3430
3430
 
3431
+ context 'when provided no arguments' do
3432
+ context 'on a model class' do
3433
+ it 'returns an empty criteria' do
3434
+ Band.where.selector.should == {}
3435
+ end
3436
+ end
3437
+
3438
+ context 'on an association' do
3439
+ it 'returns an empty criteria' do
3440
+ match.records.where.selector.should == {}
3441
+ end
3442
+ end
3443
+ end
3444
+
3445
+ context 'when provided multiple arguments' do
3446
+ context 'on a model class' do
3447
+ it 'raises ArgumentError' do
3448
+ lambda do
3449
+ Band.where({foo: 1}, {bar: 2})
3450
+ end.should raise_error(ArgumentError, /where requires zero or one arguments/)
3451
+ end
3452
+ end
3453
+
3454
+ context 'on an association' do
3455
+ it 'raises ArgumentError' do
3456
+ lambda do
3457
+ match.records.where({foo: 1}, {bar: 2})
3458
+ end.should raise_error(ArgumentError, /where requires zero or one arguments/)
3459
+ end
3460
+ end
3461
+ end
3462
+
3431
3463
  context "when provided a string" do
3432
3464
 
3433
3465
  context "when the criteria is embedded" do
@@ -7,7 +7,7 @@ describe Mongoid::Persistable::Pushable do
7
7
 
8
8
  describe "#add_to_set" do
9
9
 
10
- context "when the document is a root document" do
10
+ context "when the document is a top level document" do
11
11
 
12
12
  shared_examples_for "a unique pushable root document" do
13
13
 
@@ -65,6 +65,60 @@ describe Mongoid::Persistable::Pushable do
65
65
 
66
66
  it_behaves_like "a unique pushable root document"
67
67
  end
68
+
69
+ context 'when the host model is not saved' do
70
+ context 'when attribute exists' do
71
+ let(:person) do
72
+ Person.new(aliases: [2])
73
+ end
74
+
75
+ it 'records the change' do
76
+ person.add_to_set({aliases: 1})
77
+
78
+ expect(person.aliases).to eq([2, 1])
79
+ end
80
+ end
81
+
82
+ context 'when attribute does not exist' do
83
+ let(:person) do
84
+ Person.new
85
+ end
86
+
87
+ it 'records the change' do
88
+ person.add_to_set({aliases: 1})
89
+
90
+ expect(person.aliases).to eq([1])
91
+ end
92
+ end
93
+ end
94
+
95
+ context 'when the host model is loaded from database' do
96
+ context 'when attribute exists' do
97
+ let(:person) do
98
+ Person.create!(aliases: [2])
99
+ person = Person.last
100
+ end
101
+
102
+ it 'records the change' do
103
+ person.add_to_set({aliases: 1})
104
+
105
+ expect(person.aliases).to eq([2, 1])
106
+ end
107
+ end
108
+
109
+ context 'when attribute does not exist' do
110
+ let(:person) do
111
+ Person.create!
112
+ person = Person.last
113
+ end
114
+
115
+ it 'records the change' do
116
+ person.add_to_set({aliases: 1})
117
+
118
+ expect(person.aliases).to eq([1])
119
+ end
120
+ end
121
+ end
68
122
  end
69
123
 
70
124
  context "when the document is embedded" do
@@ -16,31 +16,117 @@ describe Mongoid::Serializable do
16
16
  end
17
17
  end
18
18
 
19
- describe ".include_root_in_json" do
19
+ %i(include_root_in_json include_root_in_json?).each do |meth|
20
+ describe ".#{meth}" do
20
21
 
21
- let(:person) do
22
- Person.new
23
- end
22
+ before do
23
+ reload_model(:Minim)
24
+ end
24
25
 
25
- context "when config set to true" do
26
+ after do
27
+ Mongoid.include_root_in_json = false
28
+ reload_model(:Minim)
29
+ end
26
30
 
27
- before do
28
- Mongoid.include_root_in_json = true
31
+ context "when global config is set to true" do
32
+
33
+ before do
34
+ Mongoid.include_root_in_json = true
35
+ end
36
+
37
+ it "returns true" do
38
+ expect(Minim.public_send(meth)).to be true
39
+ end
40
+
41
+ context 'when value is overridden to false in the model class' do
42
+ before do
43
+ Minim.include_root_in_json = false
44
+ end
45
+
46
+ it 'returns false' do
47
+ expect(Minim.public_send(meth)).to be false
48
+ end
49
+ end
29
50
  end
30
51
 
31
- it "returns true" do
32
- expect(person.include_root_in_json).to be true
52
+ context "when global config set to false" do
53
+
54
+ before do
55
+ Mongoid.include_root_in_json = false
56
+ end
57
+
58
+ it "returns false" do
59
+ expect(Minim.public_send(meth)).to be false
60
+ end
61
+
62
+ context 'when value is overridden to true in the model class' do
63
+ before do
64
+ Minim.include_root_in_json = true
65
+ end
66
+
67
+ it 'returns true' do
68
+ expect(Minim.public_send(meth)).to be true
69
+ end
70
+ end
33
71
  end
34
72
  end
35
73
 
36
- context "when config set to false" do
74
+ describe "#include_root_in_json" do
37
75
 
38
76
  before do
77
+ reload_model(:Minim)
78
+ end
79
+
80
+ after do
39
81
  Mongoid.include_root_in_json = false
82
+ reload_model(:Minim)
83
+ end
84
+
85
+ let(:minim) do
86
+ Minim.new
87
+ end
88
+
89
+ context "when global config is set to true" do
90
+
91
+ before do
92
+ Minim.include_root_in_json.should be false
93
+ Mongoid.include_root_in_json = true
94
+ end
95
+
96
+ it "returns true" do
97
+ expect(minim.public_send(meth)).to be true
98
+ end
99
+
100
+ context 'when value is overridden to false in the model class' do
101
+ before do
102
+ Minim.include_root_in_json = false
103
+ end
104
+
105
+ it 'returns false' do
106
+ expect(minim.public_send(meth)).to be false
107
+ end
108
+ end
40
109
  end
41
110
 
42
- it "returns false" do
43
- expect(person.include_root_in_json).to be false
111
+ context "when global config set to false" do
112
+
113
+ before do
114
+ Mongoid.include_root_in_json = false
115
+ end
116
+
117
+ it "returns false" do
118
+ expect(minim.public_send(meth)).to be false
119
+ end
120
+
121
+ context 'when value is overridden to true in the model class' do
122
+ before do
123
+ Minim.include_root_in_json = true
124
+ end
125
+
126
+ it 'returns true' do
127
+ expect(minim.public_send(meth)).to be true
128
+ end
129
+ end
44
130
  end
45
131
  end
46
132
  end
@@ -773,32 +859,57 @@ describe Mongoid::Serializable do
773
859
 
774
860
  describe "#to_json" do
775
861
 
776
- let(:person) do
777
- Person.new
862
+ let(:account) do
863
+ Account.new
778
864
  end
779
865
 
780
- context "when including root in json" do
866
+ context "when including root in json via Mongoid" do
781
867
 
782
868
  before do
869
+ account.include_root_in_json.should be false
783
870
  Mongoid.include_root_in_json = true
784
871
  end
785
872
 
873
+ after do
874
+ Mongoid.include_root_in_json = false
875
+ end
876
+
786
877
  it "uses the mongoid configuration" do
787
- expect(person.to_json).to include("person")
878
+ expect(JSON.parse(account.to_json)).to have_key("account")
879
+ end
880
+ end
881
+
882
+ context "when including root in json via class" do
883
+
884
+ before do
885
+ account.include_root_in_json.should be false
886
+ Account.include_root_in_json = true
887
+ end
888
+
889
+ after do
890
+ Account.include_root_in_json = false
891
+ end
892
+
893
+ it "uses the class configuration" do
894
+ expect(JSON.parse(account.to_json)).to have_key("account")
788
895
  end
789
896
  end
790
897
 
791
898
  context "when not including root in json" do
792
899
 
793
900
  before do
794
- Mongoid.include_root_in_json = false
901
+ account.include_root_in_json.should be false
795
902
  end
796
903
 
797
904
  it "uses the mongoid configuration" do
798
- expect(person.to_json).to_not include("person")
905
+ expect(JSON.parse(account.to_json)).not_to have_key("account")
799
906
  end
800
907
  end
801
908
 
909
+ let(:person) do
910
+ Person.new
911
+ end
912
+
802
913
  context "when serializing a relation directly" do
803
914
 
804
915
  context "when serializing an embeds many" do