mongoid 4.0.0.alpha2 → 4.0.0.beta1

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -0
  3. data/README.md +3 -3
  4. data/lib/config/locales/en.yml +13 -0
  5. data/lib/mongoid.rb +3 -1
  6. data/lib/mongoid/atomic.rb +1 -1
  7. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  8. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  9. data/lib/mongoid/attributes.rb +23 -1
  10. data/lib/mongoid/attributes/processing.rb +1 -1
  11. data/lib/mongoid/composable.rb +3 -2
  12. data/lib/mongoid/contextual/command.rb +0 -26
  13. data/lib/mongoid/contextual/geo_near.rb +1 -1
  14. data/lib/mongoid/contextual/mongo.rb +6 -29
  15. data/lib/mongoid/contextual/text_search.rb +3 -5
  16. data/lib/mongoid/criteria.rb +1 -1
  17. data/lib/mongoid/criteria/modifiable.rb +27 -7
  18. data/lib/mongoid/criteria/permission.rb +70 -0
  19. data/lib/mongoid/document.rb +5 -6
  20. data/lib/mongoid/errors.rb +2 -0
  21. data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
  22. data/lib/mongoid/errors/readonly_document.rb +24 -0
  23. data/lib/mongoid/extensions/boolean.rb +1 -0
  24. data/lib/mongoid/extensions/hash.rb +1 -1
  25. data/lib/mongoid/factory.rb +5 -3
  26. data/lib/mongoid/fields.rb +32 -0
  27. data/lib/mongoid/fields/localized.rb +1 -1
  28. data/lib/mongoid/fields/standard.rb +1 -1
  29. data/lib/mongoid/findable.rb +1 -0
  30. data/lib/mongoid/interceptable.rb +11 -6
  31. data/lib/mongoid/log_subscriber.rb +34 -1
  32. data/lib/mongoid/persistable/deletable.rb +1 -0
  33. data/lib/mongoid/persistable/destroyable.rb +7 -2
  34. data/lib/mongoid/persistable/updatable.rb +27 -26
  35. data/lib/mongoid/query_cache.rb +246 -0
  36. data/lib/mongoid/railties/database.rake +4 -26
  37. data/lib/mongoid/relations.rb +8 -22
  38. data/lib/mongoid/relations/accessors.rb +0 -3
  39. data/lib/mongoid/relations/binding.rb +1 -1
  40. data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
  41. data/lib/mongoid/relations/eager.rb +5 -6
  42. data/lib/mongoid/relations/eager/base.rb +97 -5
  43. data/lib/mongoid/relations/eager/belongs_to.rb +1 -0
  44. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +16 -9
  45. data/lib/mongoid/relations/eager/has_many.rb +1 -0
  46. data/lib/mongoid/relations/eager/has_one.rb +1 -0
  47. data/lib/mongoid/relations/embedded/batchable.rb +1 -1
  48. data/lib/mongoid/relations/embedded/in.rb +4 -4
  49. data/lib/mongoid/relations/embedded/many.rb +7 -5
  50. data/lib/mongoid/relations/embedded/one.rb +1 -1
  51. data/lib/mongoid/relations/macros.rb +1 -0
  52. data/lib/mongoid/relations/marshalable.rb +3 -3
  53. data/lib/mongoid/relations/proxy.rb +12 -10
  54. data/lib/mongoid/relations/referenced/in.rb +2 -2
  55. data/lib/mongoid/relations/referenced/many.rb +9 -9
  56. data/lib/mongoid/relations/referenced/many_to_many.rb +7 -7
  57. data/lib/mongoid/relations/referenced/one.rb +4 -4
  58. data/lib/mongoid/{state.rb → stateful.rb} +13 -1
  59. data/lib/mongoid/tasks/database.rake +31 -0
  60. data/lib/mongoid/tasks/database.rb +107 -0
  61. data/lib/mongoid/threaded.rb +0 -47
  62. data/lib/mongoid/validatable/uniqueness.rb +4 -16
  63. data/lib/mongoid/version.rb +1 -1
  64. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +0 -3
  65. data/lib/rails/mongoid.rb +0 -124
  66. data/spec/app/models/edit.rb +5 -0
  67. data/spec/app/models/even.rb +7 -0
  68. data/spec/app/models/line_item.rb +1 -1
  69. data/spec/app/models/note.rb +2 -0
  70. data/spec/app/models/odd.rb +7 -0
  71. data/spec/app/models/record.rb +5 -0
  72. data/spec/app/models/wiki_page.rb +1 -1
  73. data/spec/mongoid/attributes_spec.rb +76 -1
  74. data/spec/mongoid/changeable_spec.rb +6 -2
  75. data/spec/mongoid/contextual/mongo_spec.rb +3 -1
  76. data/spec/mongoid/contextual/text_search_spec.rb +3 -1
  77. data/spec/mongoid/criteria/modifiable_spec.rb +192 -0
  78. data/spec/mongoid/criteria_spec.rb +6 -2
  79. data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
  80. data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
  81. data/spec/mongoid/fields/localized_spec.rb +15 -0
  82. data/spec/mongoid/fields_spec.rb +88 -2
  83. data/spec/mongoid/log_subscriber_spec.rb +3 -3
  84. data/spec/mongoid/persistable/deletable_spec.rb +14 -1
  85. data/spec/mongoid/persistable/destroyable_spec.rb +45 -1
  86. data/spec/mongoid/persistable/savable_spec.rb +34 -5
  87. data/spec/mongoid/query_cache_spec.rb +197 -0
  88. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +2 -2
  89. data/spec/mongoid/relations/builders/referenced/many_spec.rb +1 -1
  90. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +11 -37
  91. data/spec/mongoid/relations/eager/has_one_spec.rb +1 -1
  92. data/spec/mongoid/relations/embedded/in_spec.rb +1 -1
  93. data/spec/mongoid/relations/embedded/many_spec.rb +10 -10
  94. data/spec/mongoid/relations/embedded/one_spec.rb +10 -2
  95. data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
  96. data/spec/mongoid/relations/referenced/many_spec.rb +37 -2
  97. data/spec/mongoid/relations/touchable_spec.rb +20 -0
  98. data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +26 -1
  99. data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
  100. data/spec/mongoid/tasks/database_spec.rb +148 -0
  101. data/spec/mongoid/validatable/uniqueness_spec.rb +7 -0
  102. data/spec/rails/mongoid_spec.rb +0 -316
  103. data/spec/spec_helper.rb +1 -0
  104. metadata +30 -8
@@ -0,0 +1,148 @@
1
+ require "spec_helper"
2
+
3
+ describe "Mongoid::Tasks::Database" do
4
+
5
+ let(:logger) do
6
+ double("logger").tap do |log|
7
+ allow(log).to receive(:info)
8
+ end
9
+ end
10
+
11
+ before do
12
+ allow(Mongoid::Tasks::Database).to receive(:logger).and_return(logger)
13
+ end
14
+
15
+ let(:models) do
16
+ [ User, Account, Address ]
17
+ end
18
+
19
+ describe ".create_indexes" do
20
+
21
+ let!(:klass) do
22
+ User
23
+ end
24
+
25
+ let(:indexes) do
26
+ Mongoid::Tasks::Database.create_indexes(models)
27
+ end
28
+
29
+ context "with ordinary Rails models" do
30
+
31
+ it "creates the indexes for the models" do
32
+ expect(klass).to receive(:create_indexes).once
33
+ indexes
34
+ end
35
+ end
36
+
37
+ context "with a model without indexes" do
38
+
39
+ let(:klass) do
40
+ Account
41
+ end
42
+
43
+ it "does nothing" do
44
+ expect(klass).to receive(:create_indexes).never
45
+ indexes
46
+ end
47
+ end
48
+
49
+ context "when an exception is raised" do
50
+
51
+ it "is not swallowed" do
52
+ expect(klass).to receive(:create_indexes).and_raise(ArgumentError)
53
+ expect { indexes }.to raise_error(ArgumentError)
54
+ end
55
+ end
56
+
57
+ context "when index is defined on embedded model" do
58
+
59
+ let!(:klass) do
60
+ Address
61
+ end
62
+
63
+ before do
64
+ klass.index(street: 1)
65
+ end
66
+
67
+ it "does nothing, but logging" do
68
+ expect(klass).to receive(:create_indexes).never
69
+ indexes
70
+ end
71
+ end
72
+ end
73
+
74
+ describe ".undefined_indexes" do
75
+
76
+ before(:each) do
77
+ Mongoid::Tasks::Database.create_indexes(models)
78
+ end
79
+
80
+ let(:indexes) do
81
+ Mongoid::Tasks::Database.undefined_indexes(models)
82
+ end
83
+
84
+ it "returns the removed indexes" do
85
+ expect(indexes).to be_empty
86
+ end
87
+
88
+ context "with extra index on model collection" do
89
+
90
+ before(:each) do
91
+ User.collection.indexes.create(account_expires: 1)
92
+ end
93
+
94
+ let(:names) do
95
+ indexes[User].map{ |index| index['name'] }
96
+ end
97
+
98
+ it "should have single index returned" do
99
+ expect(names).to eq(['account_expires_1'])
100
+ end
101
+ end
102
+ end
103
+
104
+ describe ".remove_undefined_indexes" do
105
+
106
+ let(:indexes) do
107
+ User.collection.indexes
108
+ end
109
+
110
+ before(:each) do
111
+ Mongoid::Tasks::Database.create_indexes(models)
112
+ indexes.create(account_expires: 1)
113
+ Mongoid::Tasks::Database.remove_undefined_indexes(models)
114
+ end
115
+
116
+ let(:removed_indexes) do
117
+ Mongoid::Tasks::Database.undefined_indexes(models)
118
+ end
119
+
120
+ it "returns the removed indexes" do
121
+ expect(removed_indexes).to be_empty
122
+ end
123
+ end
124
+
125
+ describe ".remove_indexes" do
126
+
127
+ let!(:klass) do
128
+ User
129
+ end
130
+
131
+ let(:indexes) do
132
+ klass.collection.indexes
133
+ end
134
+
135
+ before :each do
136
+ Mongoid::Tasks::Database.create_indexes(models)
137
+ Mongoid::Tasks::Database.remove_indexes(models)
138
+ end
139
+
140
+ it "removes indexes from klass" do
141
+ expect(indexes.reject{ |doc| doc["name"] == "_id_" }).to be_empty
142
+ end
143
+
144
+ it "leaves _id index untouched" do
145
+ expect(indexes.select{ |doc| doc["name"] == "_id_" }).to_not be_empty
146
+ end
147
+ end
148
+ end
@@ -1031,6 +1031,13 @@ describe Mongoid::Validatable::UniquenessValidator do
1031
1031
  end
1032
1032
  end
1033
1033
 
1034
+ context "when not allowing nil" do
1035
+
1036
+ it "raises a validation error" do
1037
+ expect { LineItem.create! }.to raise_error Mongoid::Errors::Validations
1038
+ end
1039
+ end
1040
+
1034
1041
  context "when allowing nil" do
1035
1042
 
1036
1043
  before do
@@ -9,322 +9,6 @@ describe "Rails::Mongoid" do
9
9
  end
10
10
  end
11
11
 
12
- describe ".create_indexes" do
13
-
14
- let(:logger) do
15
- double
16
- end
17
-
18
- let!(:klass) do
19
- User
20
- end
21
-
22
- let(:model_paths) do
23
- [ "spec/app/models/user.rb" ]
24
- end
25
-
26
- let(:indexes) do
27
- Rails::Mongoid.create_indexes
28
- end
29
-
30
- context "with ordinary Rails models" do
31
-
32
- it "creates the indexes for the models" do
33
- expect(klass).to receive(:create_indexes).once
34
- indexes
35
- end
36
- end
37
-
38
- context "with a model without indexes" do
39
-
40
- let(:klass) do
41
- Account
42
- end
43
-
44
- it "does nothing" do
45
- expect(klass).to receive(:create_indexes).never
46
- indexes
47
- end
48
- end
49
-
50
- context "when an exception is raised" do
51
-
52
- it "is not swallowed" do
53
- expect(klass).to receive(:create_indexes).and_raise(ArgumentError)
54
- expect { indexes }.to raise_error(ArgumentError)
55
- end
56
- end
57
-
58
- context "when index is defined on embedded model" do
59
-
60
- let!(:klass) do
61
- Address
62
- end
63
-
64
- before do
65
- klass.index(street: 1)
66
- end
67
-
68
- it "does nothing, but logging" do
69
- expect(klass).to receive(:create_indexes).never
70
- indexes
71
- end
72
- end
73
- end
74
-
75
- describe ".undefined_indexes" do
76
-
77
- before(:each) do
78
- Rails::Mongoid.create_indexes
79
- end
80
-
81
- let(:indexes) do
82
- Rails::Mongoid.undefined_indexes
83
- end
84
-
85
- it "returns the removed indexes" do
86
- expect(indexes).to be_empty
87
- end
88
-
89
- context "with extra index on model collection" do
90
-
91
- before(:each) do
92
- User.collection.indexes.create(account_expires: 1)
93
- end
94
-
95
- let(:names) do
96
- indexes[User].map{ |index| index['name'] }
97
- end
98
-
99
- it "should have single index returned" do
100
- expect(names).to eq(['account_expires_1'])
101
- end
102
- end
103
- end
104
-
105
- describe ".remove_undefined_indexes" do
106
-
107
- let(:logger) do
108
- double
109
- end
110
-
111
- let(:indexes) do
112
- User.collection.indexes
113
- end
114
-
115
- before(:each) do
116
- Rails::Mongoid.create_indexes
117
- indexes.create(account_expires: 1)
118
- Rails::Mongoid.remove_undefined_indexes
119
- end
120
-
121
- let(:removed_indexes) do
122
- Rails::Mongoid.undefined_indexes
123
- end
124
-
125
- it "returns the removed indexes" do
126
- expect(removed_indexes).to be_empty
127
- end
128
- end
129
-
130
- describe ".remove_indexes" do
131
-
132
- let(:logger) do
133
- double
134
- end
135
-
136
- let!(:klass) do
137
- User
138
- end
139
-
140
- let(:indexes) do
141
- klass.collection.indexes
142
- end
143
-
144
- before :each do
145
- Rails::Mongoid.create_indexes
146
- Rails::Mongoid.remove_indexes
147
- end
148
-
149
- it "removes indexes from klass" do
150
- expect(indexes.reject{ |doc| doc["name"] == "_id_" }).to be_empty
151
- end
152
-
153
- it "leaves _id index untouched" do
154
- expect(indexes.select{ |doc| doc["name"] == "_id_" }).to_not be_empty
155
- end
156
- end
157
-
158
- describe ".determine_model" do
159
-
160
- let(:logger) do
161
- double
162
- end
163
-
164
- let!(:klass) do
165
- User
166
- end
167
-
168
- let(:file) do
169
- "app/models/user.rb"
170
- end
171
-
172
- let(:model) do
173
- Rails::Mongoid.send(:determine_model, file, logger)
174
- end
175
-
176
- class EasyURI
177
- end
178
-
179
- module Twitter
180
- class Follow
181
- include Mongoid::Document
182
- end
183
-
184
- module List
185
- class Tweet
186
- include Mongoid::Document
187
- end
188
- end
189
- end
190
-
191
- context "when file is nil" do
192
-
193
- let(:file) do
194
- nil
195
- end
196
-
197
- it "returns nil" do
198
- expect(model).to be_nil
199
- end
200
- end
201
-
202
- context "when logger is nil" do
203
-
204
- let(:logger) do
205
- nil
206
- end
207
-
208
- it "returns nil" do
209
- expect(model).to be_nil
210
- end
211
- end
212
-
213
- context "when path is invalid" do
214
-
215
- let(:file) do
216
- "fu/bar.rb"
217
- end
218
-
219
- it "returns nil" do
220
- expect(model).to be_nil
221
- end
222
- end
223
-
224
- context "when file cannot be constantize" do
225
-
226
- let(:file) do
227
- "app/models/easy_uri.rb"
228
- end
229
-
230
- before do
231
- expect(logger).to receive(:info)
232
- end
233
-
234
- it "returns nil" do
235
- expect(model).to be_nil
236
- end
237
- end
238
-
239
- context "when file is not in a subdir" do
240
-
241
- context "when file is from normal model" do
242
-
243
- it "returns klass" do
244
- expect(model).to eq(klass)
245
- end
246
- end
247
-
248
- context "when file is in a module" do
249
-
250
- let(:klass) do
251
- Twitter::Follow
252
- end
253
-
254
- let(:file) do
255
- "app/models/follow.rb"
256
- end
257
-
258
- it "logs the class without an error" do
259
- expect(logger).to receive(:info)
260
- expect {
261
- expect(model).to be_nil
262
- }.not_to raise_error
263
- end
264
- end
265
- end
266
-
267
- context "when file is in a subdir" do
268
-
269
- context "with file from normal model" do
270
-
271
- let(:file) do
272
- "app/models/fu/user.rb"
273
- end
274
-
275
- it "returns klass" do
276
- expect(logger).to receive(:info)
277
- expect(model).to eq(klass)
278
- end
279
- end
280
-
281
- context "when file is in a module" do
282
-
283
- let(:klass) do
284
- Twitter::Follow
285
- end
286
-
287
- let(:file) do
288
- "app/models/twitter/follow.rb"
289
- end
290
-
291
- it "returns klass in module" do
292
- expect(model).to eq(klass)
293
- end
294
- end
295
-
296
- context "when file is in two modules" do
297
-
298
- let(:klass) do
299
- Twitter::List::Tweet
300
- end
301
-
302
- let(:file) do
303
- "app/models/twitter/list/tweet.rb"
304
- end
305
-
306
- it "returns klass in module" do
307
- expect(model).to eq(klass)
308
- end
309
- end
310
- end
311
-
312
- context "with models present in Rails engines" do
313
-
314
- let(:file) do
315
- "/gem_path/engines/some_engine_gem/app/models/user.rb"
316
- end
317
-
318
- let(:klass) do
319
- User
320
- end
321
-
322
- it "requires the models by base name from the engine's app/models dir" do
323
- expect(model).to eq(klass)
324
- end
325
- end
326
- end
327
-
328
12
  describe ".preload_models" do
329
13
 
330
14
  let(:app) do