mongoid 4.0.0.alpha1 → 4.0.0.alpha2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +1 -1
- data/lib/config/locales/en.yml +4 -6
- data/lib/mongoid/attributes/processing.rb +1 -1
- data/lib/mongoid/contextual.rb +2 -0
- data/lib/mongoid/contextual/map_reduce.rb +3 -1
- data/lib/mongoid/contextual/none.rb +90 -0
- data/lib/mongoid/criteria.rb +25 -0
- data/lib/mongoid/extensions/array.rb +1 -1
- data/lib/mongoid/extensions/big_decimal.rb +1 -1
- data/lib/mongoid/extensions/date.rb +1 -1
- data/lib/mongoid/extensions/date_time.rb +3 -3
- data/lib/mongoid/extensions/float.rb +1 -1
- data/lib/mongoid/extensions/hash.rb +1 -1
- data/lib/mongoid/extensions/integer.rb +1 -1
- data/lib/mongoid/extensions/object.rb +3 -3
- data/lib/mongoid/extensions/object_id.rb +1 -1
- data/lib/mongoid/extensions/range.rb +1 -1
- data/lib/mongoid/extensions/regexp.rb +1 -1
- data/lib/mongoid/extensions/set.rb +1 -1
- data/lib/mongoid/extensions/string.rb +1 -1
- data/lib/mongoid/extensions/symbol.rb +1 -1
- data/lib/mongoid/extensions/time.rb +1 -1
- data/lib/mongoid/extensions/time_with_zone.rb +1 -1
- data/lib/mongoid/findable.rb +1 -0
- data/lib/mongoid/interceptable.rb +4 -2
- data/lib/mongoid/persistable.rb +4 -3
- data/lib/mongoid/relations/embedded/many.rb +1 -1
- data/lib/mongoid/relations/metadata.rb +8 -4
- data/lib/mongoid/relations/referenced/many.rb +1 -1
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/scopable.rb +2 -26
- data/lib/mongoid/validatable/uniqueness.rb +13 -0
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +0 -4
- data/spec/app/models/acolyte.rb +1 -1
- data/spec/app/models/address.rb +2 -2
- data/spec/app/models/appointment.rb +1 -1
- data/spec/app/models/audio.rb +1 -1
- data/spec/app/models/dog.rb +1 -1
- data/spec/app/models/event.rb +1 -1
- data/spec/app/models/house.rb +1 -1
- data/spec/app/models/message.rb +8 -0
- data/spec/app/models/person.rb +3 -2
- data/spec/app/models/player.rb +2 -2
- data/spec/app/models/post.rb +3 -2
- data/spec/app/models/preference.rb +1 -1
- data/spec/app/models/sound.rb +1 -1
- data/spec/app/models/symptom.rb +1 -1
- data/spec/app/models/tree.rb +2 -2
- data/spec/app/models/video.rb +1 -1
- data/spec/mongoid/attributes_spec.rb +3 -3
- data/spec/mongoid/changeable_spec.rb +3 -3
- data/spec/mongoid/contextual/mongo_spec.rb +14 -14
- data/spec/mongoid/contextual/none_spec.rb +127 -0
- data/spec/mongoid/criteria/scopable_spec.rb +6 -6
- data/spec/mongoid/criteria_spec.rb +52 -96
- data/spec/mongoid/errors/invalid_scope_spec.rb +2 -2
- data/spec/mongoid/errors/mongoid_error_spec.rb +1 -1
- data/spec/mongoid/extensions/date_time_spec.rb +1 -1
- data/spec/mongoid/fields_spec.rb +6 -7
- data/spec/mongoid/findable_spec.rb +65 -0
- data/spec/mongoid/interceptable_spec.rb +11 -11
- data/spec/mongoid/persistable_spec.rb +4 -4
- data/spec/mongoid/relations/auto_save_spec.rb +1 -1
- data/spec/mongoid/relations/bindings/embedded/in_spec.rb +5 -5
- data/spec/mongoid/relations/bindings/embedded/many_spec.rb +1 -1
- data/spec/mongoid/relations/bindings/embedded/one_spec.rb +2 -2
- data/spec/mongoid/relations/bindings/referenced/in_spec.rb +14 -14
- data/spec/mongoid/relations/bindings/referenced/many_spec.rb +4 -4
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +10 -10
- data/spec/mongoid/relations/bindings/referenced/one_spec.rb +6 -6
- data/spec/mongoid/relations/builders/referenced/in_spec.rb +2 -2
- data/spec/mongoid/relations/builders/referenced/one_spec.rb +1 -1
- data/spec/mongoid/relations/cascading/delete_spec.rb +2 -2
- data/spec/mongoid/relations/cascading/destroy_spec.rb +4 -4
- data/spec/mongoid/relations/cascading/nullify_spec.rb +2 -2
- data/spec/mongoid/relations/cascading/restrict_spec.rb +4 -4
- data/spec/mongoid/relations/eager_spec.rb +6 -6
- data/spec/mongoid/relations/embedded/many_spec.rb +36 -5
- data/spec/mongoid/relations/metadata_spec.rb +34 -15
- data/spec/mongoid/relations/referenced/many_spec.rb +19 -4
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +7 -7
- data/spec/mongoid/relations/referenced/one_spec.rb +1 -1
- data/spec/mongoid/relations/targets/enumerable_spec.rb +2 -2
- data/spec/mongoid/relations/touchable_spec.rb +17 -0
- data/spec/mongoid/scopable_spec.rb +17 -40
- data/spec/mongoid/sessions/options_spec.rb +1 -1
- data/spec/mongoid/timestamps/timeless_spec.rb +6 -6
- data/spec/mongoid/timestamps/updated/short_spec.rb +1 -1
- data/spec/mongoid/timestamps/updated_spec.rb +1 -1
- data/spec/mongoid/timestamps_spec.rb +2 -2
- data/spec/mongoid/validatable/associated_spec.rb +4 -4
- data/spec/mongoid/validatable/length_spec.rb +7 -7
- data/spec/mongoid/validatable/presence_spec.rb +6 -6
- data/spec/mongoid/validatable/uniqueness_spec.rb +44 -3
- data/spec/rails/mongoid_spec.rb +20 -20
- data/spec/spec_helper.rb +1 -0
- metadata +55 -50
@@ -910,9 +910,13 @@ module Mongoid
|
|
910
910
|
# @since 3.0.0
|
911
911
|
def find_from_parts(modules)
|
912
912
|
modules.find do |mod|
|
913
|
-
|
914
|
-
|
915
|
-
|
913
|
+
if mod.blank?
|
914
|
+
false
|
915
|
+
else
|
916
|
+
ActiveSupport::Inflector.constantize(mod).constants.include?(
|
917
|
+
name.to_s.classify.to_sym
|
918
|
+
)
|
919
|
+
end
|
916
920
|
end
|
917
921
|
end
|
918
922
|
|
@@ -1044,7 +1048,7 @@ module Mongoid
|
|
1044
1048
|
def inverse_relation_candidates
|
1045
1049
|
relations_metadata.select do |meta|
|
1046
1050
|
next if meta.name == name
|
1047
|
-
meta.class_name == inverse_class_name
|
1051
|
+
(meta.class_name == inverse_class_name) && !meta.forced_nil_inverse?
|
1048
1052
|
end
|
1049
1053
|
end
|
1050
1054
|
|
data/lib/mongoid/scopable.rb
CHANGED
@@ -143,7 +143,7 @@ module Mongoid
|
|
143
143
|
check_scope_validity(value)
|
144
144
|
check_scope_name(normalized)
|
145
145
|
_declared_scopes[normalized] = {
|
146
|
-
scope:
|
146
|
+
scope: value,
|
147
147
|
extension: Module.new(&block)
|
148
148
|
}
|
149
149
|
define_scope_method(normalized)
|
@@ -302,7 +302,7 @@ module Mongoid
|
|
302
302
|
#
|
303
303
|
# @since 3.0.0
|
304
304
|
def check_scope_validity(value)
|
305
|
-
unless value.respond_to?(:
|
305
|
+
unless value.respond_to?(:call)
|
306
306
|
raise Errors::InvalidScope.new(self, value)
|
307
307
|
end
|
308
308
|
end
|
@@ -350,30 +350,6 @@ module Mongoid
|
|
350
350
|
value.to_proc
|
351
351
|
end
|
352
352
|
end
|
353
|
-
|
354
|
-
# Strip the default scope from the provided value, if it is a criteria.
|
355
|
-
# This is used by named scopes - they should not have the default scoping
|
356
|
-
# applied to them.
|
357
|
-
#
|
358
|
-
# @api private
|
359
|
-
#
|
360
|
-
# @example Strip the default scope.
|
361
|
-
# Model.strip_default_scope
|
362
|
-
#
|
363
|
-
# @param [ Proc, Criteria ] value The value to strip from.
|
364
|
-
#
|
365
|
-
# @return [ Proc ] The stripped criteria, as a proc.
|
366
|
-
#
|
367
|
-
# @since 3.0.0
|
368
|
-
def strip_default_scope(value)
|
369
|
-
if value.is_a?(Criteria)
|
370
|
-
default = default_scoping.try(:call)
|
371
|
-
value.remove_scoping(default)
|
372
|
-
value.to_proc
|
373
|
-
else
|
374
|
-
value
|
375
|
-
end
|
376
|
-
end
|
377
353
|
end
|
378
354
|
end
|
379
355
|
end
|
@@ -13,6 +13,16 @@ module Mongoid
|
|
13
13
|
#
|
14
14
|
# validates_uniqueness_of :title
|
15
15
|
# end
|
16
|
+
#
|
17
|
+
# It is also possible to limit the uniqueness constraint to a set of
|
18
|
+
# records matching certain conditions:
|
19
|
+
# class Person
|
20
|
+
# include Mongoid::Document
|
21
|
+
# field :title
|
22
|
+
# field :active, type: Boolean
|
23
|
+
#
|
24
|
+
# validates_uniqueness_of :title, conditions: -> {where(active: true)}
|
25
|
+
# end
|
16
26
|
class UniquenessValidator < ActiveModel::EachValidator
|
17
27
|
include Queryable
|
18
28
|
|
@@ -253,6 +263,7 @@ module Mongoid
|
|
253
263
|
return if skip_validation?(document)
|
254
264
|
relation = document._parent.send(document.metadata_name)
|
255
265
|
criteria = create_criteria(relation, document, attribute, value)
|
266
|
+
criteria = criteria.merge(options[:conditions].call) if options[:conditions]
|
256
267
|
add_error(document, attribute, value) if criteria.count > 1
|
257
268
|
end
|
258
269
|
|
@@ -270,6 +281,8 @@ module Mongoid
|
|
270
281
|
# @since 2.4.10
|
271
282
|
def validate_root(document, attribute, value)
|
272
283
|
criteria = create_criteria(klass || document.class, document, attribute, value)
|
284
|
+
criteria = criteria.merge(options[:conditions].call) if options[:conditions]
|
285
|
+
|
273
286
|
if criteria.with(persistence_options(criteria)).exists?
|
274
287
|
add_error(document, attribute, value)
|
275
288
|
end
|
data/lib/mongoid/version.rb
CHANGED
@@ -53,10 +53,6 @@ development:
|
|
53
53
|
# existing method. (default: false)
|
54
54
|
# scope_overwrite_exception: false
|
55
55
|
|
56
|
-
# Skip the database version check, used when connecting to a db without
|
57
|
-
# admin access. (default: false)
|
58
|
-
# skip_version_check: false
|
59
|
-
|
60
56
|
# Use Active Support's time zone in conversions. (default: true)
|
61
57
|
# use_activesupport_time_zone: true
|
62
58
|
|
data/spec/app/models/acolyte.rb
CHANGED
data/spec/app/models/address.rb
CHANGED
@@ -43,8 +43,8 @@ class Address
|
|
43
43
|
belongs_to :account
|
44
44
|
belongs_to :band
|
45
45
|
|
46
|
-
scope :without_postcode, where(postcode: nil)
|
47
|
-
scope :rodeo, where(street: "Rodeo Dr") do
|
46
|
+
scope :without_postcode, ->{ where(postcode: nil) }
|
47
|
+
scope :rodeo, ->{ where(street: "Rodeo Dr") } do
|
48
48
|
def mansion?
|
49
49
|
all? { |address| address.street == "Rodeo Dr" }
|
50
50
|
end
|
data/spec/app/models/audio.rb
CHANGED
data/spec/app/models/dog.rb
CHANGED
data/spec/app/models/event.rb
CHANGED
data/spec/app/models/house.rb
CHANGED
data/spec/app/models/person.rb
CHANGED
@@ -64,6 +64,7 @@ class Person
|
|
64
64
|
embeds_many :services, cascade_callbacks: true, validate: false
|
65
65
|
embeds_many :symptoms, validate: false
|
66
66
|
embeds_many :appointments, validate: false
|
67
|
+
embeds_many :messages, validate: false
|
67
68
|
|
68
69
|
embeds_one :passport, autobuild: true, store_as: :pass, validate: false
|
69
70
|
embeds_one :pet, class_name: "Animal", validate: false
|
@@ -124,8 +125,8 @@ class Person
|
|
124
125
|
accepts_nested_attributes_for :quiz
|
125
126
|
accepts_nested_attributes_for :services, allow_destroy: true
|
126
127
|
|
127
|
-
scope :minor, where(:age.lt => 18)
|
128
|
-
scope :without_ssn, without(:ssn)
|
128
|
+
scope :minor, ->{ where(:age.lt => 18) }
|
129
|
+
scope :without_ssn, ->{ without(:ssn) }
|
129
130
|
scope :search, ->(query){ any_of({ title: query }) }
|
130
131
|
|
131
132
|
def score_with_rescoring=(score)
|
data/spec/app/models/player.rb
CHANGED
@@ -6,13 +6,13 @@ class Player
|
|
6
6
|
field :impressions, type: Integer, default: 0
|
7
7
|
field :status
|
8
8
|
|
9
|
-
scope :active, where(active: true) do
|
9
|
+
scope :active, ->{ where(active: true) } do
|
10
10
|
def extension
|
11
11
|
"extension"
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
scope :inactive, where(active: false)
|
15
|
+
scope :inactive, ->{ where(active: false) }
|
16
16
|
scope :frags_over, ->(count) { where(:frags.gt => count) }
|
17
17
|
scope :deaths_under, ->(count) { where(:deaths.lt => count) }
|
18
18
|
scope :deaths_over, ->(count) { where(:deaths.gt => count) }
|
data/spec/app/models/post.rb
CHANGED
@@ -15,8 +15,9 @@ class Post
|
|
15
15
|
has_many :videos, validate: false
|
16
16
|
has_many :roles, validate: false
|
17
17
|
|
18
|
-
scope :recent, where(created_at: { "$lt" => Time.now, "$gt" => 30.days.ago })
|
19
|
-
scope :posting, where(:content.in => [ "Posting" ])
|
18
|
+
scope :recent, ->{ where(created_at: { "$lt" => Time.now, "$gt" => 30.days.ago }) }
|
19
|
+
scope :posting, ->{ where(:content.in => [ "Posting" ]) }
|
20
|
+
scope :open, ->{ where(title: "open") }
|
20
21
|
|
21
22
|
validates_format_of :title, without: /\$\$\$/
|
22
23
|
|
@@ -5,5 +5,5 @@ class Preference
|
|
5
5
|
field :ranking, type: Integer
|
6
6
|
has_and_belongs_to_many :people, validate: false
|
7
7
|
validates_length_of :name, minimum: 2, allow_nil: true
|
8
|
-
scope :posting, where(:value.in => [ "Posting" ])
|
8
|
+
scope :posting, ->{ where(:value.in => [ "Posting" ]) }
|
9
9
|
end
|
data/spec/app/models/sound.rb
CHANGED
data/spec/app/models/symptom.rb
CHANGED
data/spec/app/models/tree.rb
CHANGED
data/spec/app/models/video.rb
CHANGED
@@ -1044,7 +1044,7 @@ describe Mongoid::Attributes do
|
|
1044
1044
|
end
|
1045
1045
|
|
1046
1046
|
it "can set a Hash value" do
|
1047
|
-
person.map.
|
1047
|
+
expect(person.map).to eq( { somekey: "somevalue" } )
|
1048
1048
|
end
|
1049
1049
|
end
|
1050
1050
|
|
@@ -1052,7 +1052,7 @@ describe Mongoid::Attributes do
|
|
1052
1052
|
let(:person) { Person.new aliases: [ :alias_1 ] }
|
1053
1053
|
|
1054
1054
|
it "can set an Array Value" do
|
1055
|
-
person.aliases.
|
1055
|
+
expect(person.aliases).to eq([ :alias_1 ])
|
1056
1056
|
end
|
1057
1057
|
|
1058
1058
|
it "raises an error when try to set an invalid value" do
|
@@ -1079,7 +1079,7 @@ describe Mongoid::Attributes do
|
|
1079
1079
|
context "when the key has not been specified as a field" do
|
1080
1080
|
|
1081
1081
|
before do
|
1082
|
-
person.
|
1082
|
+
allow(person).to receive(:fields).and_return({})
|
1083
1083
|
end
|
1084
1084
|
|
1085
1085
|
it "returns the value" do
|
@@ -627,7 +627,7 @@ describe Mongoid::Changeable do
|
|
627
627
|
|
628
628
|
before do
|
629
629
|
person.changed_attributes["aliases"] = aliases
|
630
|
-
aliases.
|
630
|
+
expect(aliases).to receive(:clone).never
|
631
631
|
person.aliases_will_change!
|
632
632
|
end
|
633
633
|
|
@@ -757,8 +757,8 @@ describe Mongoid::Changeable do
|
|
757
757
|
end
|
758
758
|
|
759
759
|
it "returns true" do
|
760
|
-
person.changes.
|
761
|
-
person.
|
760
|
+
expect(person.changes).to_not be_empty
|
761
|
+
expect(person).to be_changed
|
762
762
|
end
|
763
763
|
end
|
764
764
|
end
|
@@ -107,7 +107,7 @@ describe Mongoid::Contextual::Mongo do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
before do
|
110
|
-
context.query.
|
110
|
+
expect(context.query).to receive(:count).once.and_return(1)
|
111
111
|
end
|
112
112
|
|
113
113
|
it "returns the count cached value after first call" do
|
@@ -438,7 +438,7 @@ describe Mongoid::Contextual::Mongo do
|
|
438
438
|
end
|
439
439
|
|
440
440
|
it "does not make any additional database queries" do
|
441
|
-
game_metadata.
|
441
|
+
expect(game_metadata).to receive(:eager_load).never
|
442
442
|
context.send(:eager_load, [])
|
443
443
|
end
|
444
444
|
end
|
@@ -497,8 +497,8 @@ describe Mongoid::Contextual::Mongo do
|
|
497
497
|
end
|
498
498
|
|
499
499
|
it "hits the database again" do
|
500
|
-
context.
|
501
|
-
context.
|
500
|
+
expect(context).to receive(:query).once.and_call_original
|
501
|
+
expect(context).to be_exists
|
502
502
|
end
|
503
503
|
end
|
504
504
|
end
|
@@ -520,7 +520,7 @@ describe Mongoid::Contextual::Mongo do
|
|
520
520
|
end
|
521
521
|
|
522
522
|
it "does not hit the database" do
|
523
|
-
context.
|
523
|
+
expect(context).to receive(:query).never
|
524
524
|
expect(context).to be_exists
|
525
525
|
end
|
526
526
|
end
|
@@ -534,7 +534,7 @@ describe Mongoid::Contextual::Mongo do
|
|
534
534
|
end
|
535
535
|
|
536
536
|
it "does not hit the database" do
|
537
|
-
context.
|
537
|
+
expect(context).to receive(:query).never
|
538
538
|
expect(context).to be_exists
|
539
539
|
end
|
540
540
|
end
|
@@ -807,7 +807,7 @@ describe Mongoid::Contextual::Mongo do
|
|
807
807
|
end
|
808
808
|
|
809
809
|
it "returns the first document without touching the database" do
|
810
|
-
context.
|
810
|
+
expect(context).to receive(:query).never
|
811
811
|
expect(context.send(method)).to eq(depeche_mode)
|
812
812
|
end
|
813
813
|
end
|
@@ -819,8 +819,8 @@ describe Mongoid::Contextual::Mongo do
|
|
819
819
|
end
|
820
820
|
|
821
821
|
it "returns the first document without touching the database" do
|
822
|
-
context.
|
823
|
-
context.send(method).
|
822
|
+
expect(context).to receive(:query).never
|
823
|
+
expect(context.send(method)).to eq(depeche_mode)
|
824
824
|
end
|
825
825
|
end
|
826
826
|
end
|
@@ -957,7 +957,7 @@ describe Mongoid::Contextual::Mongo do
|
|
957
957
|
context "when calling more than once" do
|
958
958
|
|
959
959
|
before do
|
960
|
-
context.query.
|
960
|
+
expect(context.query).to receive(:count).once.and_return(2)
|
961
961
|
end
|
962
962
|
|
963
963
|
it "returns the cached value for subsequent calls" do
|
@@ -969,7 +969,7 @@ describe Mongoid::Contextual::Mongo do
|
|
969
969
|
|
970
970
|
before do
|
971
971
|
context.entries
|
972
|
-
context.query.
|
972
|
+
expect(context.query).to receive(:count).once.and_return(2)
|
973
973
|
end
|
974
974
|
|
975
975
|
it "returns the cached value for all calls" do
|
@@ -1006,7 +1006,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1006
1006
|
context "when calling more than once" do
|
1007
1007
|
|
1008
1008
|
before do
|
1009
|
-
context.query.
|
1009
|
+
expect(context.query).to receive(:count).once.and_return(1)
|
1010
1010
|
end
|
1011
1011
|
|
1012
1012
|
it "returns the cached value for subsequent calls" do
|
@@ -1018,7 +1018,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1018
1018
|
|
1019
1019
|
before do
|
1020
1020
|
context.entries
|
1021
|
-
context.query.
|
1021
|
+
expect(context.query).to receive(:count).once.and_return(1)
|
1022
1022
|
end
|
1023
1023
|
|
1024
1024
|
it "returns the cached value for all calls" do
|
@@ -1081,7 +1081,7 @@ describe Mongoid::Contextual::Mongo do
|
|
1081
1081
|
context "when passed the symbol field name" do
|
1082
1082
|
|
1083
1083
|
it "limits query to that field" do
|
1084
|
-
criteria.
|
1084
|
+
expect(criteria).to receive(:only).with(:name).and_call_original
|
1085
1085
|
context.map(:name)
|
1086
1086
|
end
|
1087
1087
|
|