mongoid 3.1.3 → 3.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6a93ef3b8e16abfb336265ee706bf8dc3ca62f89
4
- data.tar.gz: 8d27fd207900247df10d6c3e49b7eebf088b97b6
3
+ metadata.gz: e112d2050bea71c9b4ec085c77518391924fd579
4
+ data.tar.gz: 7b83e17ffe01d545d5a08833d1a07e8ef120a2bb
5
5
  SHA512:
6
- metadata.gz: f3ee03829a223c53df67171aec6ef170937e59f299e8f21e5cbc66ea10064455c4443addeb64e0c5b713acc8cec4421213f7e949c86f832aa60ff4c87620b015
7
- data.tar.gz: 1e3825ba1089fe531844c0662c2137a66a050f31e4c1f52795c545ecc860ad205e96d5dba70795375f4274428bc5b9c5c48ae1ecbf8be34251c4642f87e6d087
6
+ metadata.gz: 0344a52659debedd1ed969e05676a35c65edd806471bdcb9d8045e8404293b27451449d434d9f1d6c2174f3dc8475a9eff978bcbbaabd3f54f0a53f980b8a625
7
+ data.tar.gz: e196f3ebc85543dc36a9e6f49f1f024c993d626ab4990604ad5061961ed3e8a0cfecbfd6f3a18c048127819d9897b1f0eb25d588ed141dc4d9f8b96d7c38fbaf
@@ -7,6 +7,35 @@ For instructions on upgrading to newer versions, visit
7
7
 
8
8
  ### Resolved Issues
9
9
 
10
+ * \#3044 Ensure enumerable targets match arrays in case statements.
11
+
12
+ * \#3034 `first_or_create` on criterion now properly passes the block to create
13
+ instead of calling after the document was created.
14
+
15
+ * \#3021 Removed `mongoid.yml` warning from initializer, this is now handled by
16
+ the session configuration options.
17
+
18
+ * \#3018 Uniqueness validator now properly serializes values in its check.
19
+ (Jerry Clinesmith)
20
+
21
+ * \#3011 Fixed aliased field support for uniqueness validation. (Johnny Shields)
22
+
23
+ * \#3008 Fixed subclasses not being able to inherit scopes properly when scope
24
+ is added post class load. (Mike Dillon)
25
+
26
+ * \#2991 `Document.timeless` now properly scopes to the instance and not thread.
27
+
28
+ * \#2980 Dynamic fields now properly handle in place editing of hashes and
29
+ arrays. (Matthew Widmann)
30
+
31
+ * \#2979 `pluck` no longer modifies the context in place. (Brian Goff)
32
+
33
+ * \#2970 Fixed counter cache to properly use the name of the relation if available
34
+ then the inverse class name second if not.
35
+
36
+ * \#2959 Nested attributes will now respect `autosave: false` if defined on the
37
+ relation.
38
+
10
39
  * \#2944 Fixed uniqueness validation for localized fields when case insensitive
11
40
  is true. (Vladimir Zhukov)
12
41
 
@@ -75,14 +75,6 @@ en:
75
75
  expecting the option to be there, please consult the following page
76
76
  with repect to Mongoid's configuration:\n\n
77
77
  \_\_http://mongoid.org/en/mongoid/docs/installation.html"
78
- invalid_database:
79
- message: "Database should be a Mongo::DB, not %{name}."
80
- summary: "When setting a master database in the Mongoid configuration
81
- it must be an actual instance of a Mongo::DB, and not just a name
82
- of the database. This check is performed when calling
83
- Mongoid.master = object."
84
- resolution: "Make sure that when setting the configuration
85
- programatically that you are passing an actual db instance."
86
78
  invalid_field:
87
79
  message: "Defining a field named '%{name}' is not allowed."
88
80
  summary: "Defining this field would override the method '%{name}',
@@ -252,6 +252,7 @@ module Mongoid
252
252
 
253
253
  class_eval <<-READER
254
254
  def #{name}
255
+ attribute_will_change!(#{name.inspect})
255
256
  read_attribute(#{name.inspect})
256
257
  end
257
258
  READER
@@ -270,6 +271,7 @@ module Mongoid
270
271
  def define_dynamic_before_type_cast_reader(name)
271
272
  class_eval <<-READER
272
273
  def #{name}_before_type_cast
274
+ attribute_will_change!(#{name.inspect})
273
275
  read_attribute_before_type_cast(#{name.inspect})
274
276
  end
275
277
  READER
@@ -322,10 +324,12 @@ module Mongoid
322
324
  write_attribute(getter, args.first)
323
325
  elsif attr.before_type_cast?
324
326
  define_dynamic_before_type_cast_reader(attr.reader)
327
+ attribute_will_change!(attr.reader)
325
328
  read_attribute_before_type_cast(attr.reader)
326
329
  else
327
330
  getter = attr.reader
328
331
  define_dynamic_reader(getter)
332
+ attribute_will_change!(attr.reader)
329
333
  read_attribute(getter)
330
334
  end
331
335
  end
@@ -337,7 +337,7 @@ module Mongoid
337
337
  # @since 3.1.0
338
338
  def pluck(field)
339
339
  normalized = klass.database_field_name(field)
340
- query.select(normalized => 1).map{ |doc| doc[normalized] }.compact
340
+ query.dup.select(normalized => 1).map{ |doc| doc[normalized] }.compact
341
341
  end
342
342
 
343
343
  # Skips the provided number of documents.
@@ -181,10 +181,8 @@ module Mongoid
181
181
  # @return [ Document ] The first or new document.
182
182
  #
183
183
  # @since 3.1.0
184
- def first_or(method, attrs = nil)
185
- document = first || create_document(method, attrs)
186
- yield(document) if block_given?
187
- document
184
+ def first_or(method, attrs = {}, &block)
185
+ first || create_document(method, attrs, &block)
188
186
  end
189
187
  end
190
188
  end
@@ -97,7 +97,7 @@ module Mongoid
97
97
  def post_persist
98
98
  reset_persisted_children
99
99
  move_changes
100
- Threaded.clear_options!
100
+ clear_timeless_option
101
101
  end
102
102
 
103
103
  # Get the previous changes on the document.
@@ -6,7 +6,6 @@ require "mongoid/errors/document_not_found"
6
6
  require "mongoid/errors/eager_load"
7
7
  require "mongoid/errors/invalid_collection"
8
8
  require "mongoid/errors/invalid_config_option"
9
- require "mongoid/errors/invalid_database"
10
9
  require "mongoid/errors/invalid_field"
11
10
  require "mongoid/errors/invalid_field_option"
12
11
  require "mongoid/errors/invalid_find"
@@ -172,7 +172,7 @@ module Mongoid
172
172
  subclass.fields = fields.dup
173
173
  subclass.pre_processed_defaults = pre_processed_defaults.dup
174
174
  subclass.post_processed_defaults = post_processed_defaults.dup
175
- subclass.scopes = scopes.dup
175
+ subclass._declared_scopes = Hash.new { |hash,key| self._declared_scopes[key] }
176
176
  subclass.autosaved_relations = autosaved_relations.dup
177
177
 
178
178
  # We only need the _type field if inheritance is in play, but need to
@@ -46,10 +46,8 @@ module Mongoid
46
46
  meth = "#{name}_attributes="
47
47
  self.nested_attributes["#{name}_attributes"] = meth
48
48
  metadata = relations[name.to_s]
49
- unless metadata
50
- raise Errors::NestedAttributesMetadataNotFound.new(self, name)
51
- end
52
- autosave(metadata.merge!(autosave: true))
49
+ raise Errors::NestedAttributesMetadataNotFound.new(self, name) unless metadata
50
+ autosave_nested_attributes(metadata)
53
51
  re_define_method(meth) do |attrs|
54
52
  _assigning do
55
53
  metadata.nested_builder(attrs, options).build(self, mass_assignment_options)
@@ -57,6 +55,24 @@ module Mongoid
57
55
  end
58
56
  end
59
57
  end
58
+
59
+ private
60
+
61
+ # Add the autosave information for the nested relation.
62
+ #
63
+ # @api private
64
+ #
65
+ # @example Add the autosave if appropriate.
66
+ # Person.autosave_nested_attributes(metadata)
67
+ #
68
+ # @param [ Metadata ] metadata The existing relation metadata.
69
+ #
70
+ # @since 3.1.4
71
+ def autosave_nested_attributes(metadata)
72
+ unless metadata.autosave == false
73
+ autosave(metadata.merge!(autosave: true))
74
+ end
75
+ end
60
76
  end
61
77
  end
62
78
  end
@@ -64,7 +64,7 @@ module Mongoid
64
64
  update({ "$set" => { paranoid_field => time }})
65
65
  @destroyed = true
66
66
  IdentityMap.remove(self)
67
- Threaded.clear_options!
67
+ clear_timeless_option
68
68
  true
69
69
  end
70
70
  alias :delete :remove
@@ -301,7 +301,6 @@ module Mongoid
301
301
  coll = collection
302
302
  deleted = coll.find(selector).count
303
303
  coll.find(selector).remove_all
304
- Threaded.clear_options!
305
304
  deleted
306
305
  end
307
306
 
@@ -88,9 +88,7 @@ module Mongoid
88
88
  #
89
89
  # @since 2.1.0
90
90
  def prepare
91
- doc = yield(document)
92
- Threaded.clear_options!
93
- doc
91
+ yield(document)
94
92
  end
95
93
 
96
94
  private
@@ -24,7 +24,7 @@ module Mongoid
24
24
  document.freeze
25
25
  document.destroyed = true
26
26
  IdentityMap.remove(document)
27
- Threaded.clear_options!
27
+ document.clear_timeless_option
28
28
  true
29
29
  end
30
30
  end
@@ -77,17 +77,6 @@ module Rails
77
77
  end
78
78
  end
79
79
 
80
- # After initialization we will warn the user if we can't find a mongoid.yml and
81
- # alert to create one.
82
- initializer "warn when configuration is missing" do
83
- config.after_initialize do
84
- unless Rails.root.join("config", "mongoid.yml").file? || ::Mongoid.configured?
85
- puts "\nMongoid config not found. Create a config file at: config/mongoid.yml"
86
- puts "to generate one run: rails generate mongoid:config\n\n"
87
- end
88
- end
89
- end
90
-
91
80
  # Set the proper error types for Rails. DocumentNotFound errors should be
92
81
  # 404s and not 500s, validation errors are 422s.
93
82
  initializer "load http errors" do |app|
@@ -62,7 +62,6 @@ module Mongoid
62
62
  )
63
63
  post_process_batch_remove(docs, method)
64
64
  end
65
- Threaded.clear_options!
66
65
  reindex
67
66
  end
68
67
 
@@ -305,6 +304,7 @@ module Mongoid
305
304
  _unscoped.delete_one(doc)
306
305
  unbind_one(doc)
307
306
  execute_callback :after_remove, doc
307
+ doc.clear_timeless_option
308
308
  doc.as_document
309
309
  end
310
310
  end
@@ -160,7 +160,7 @@ module Mongoid
160
160
  # @since 3.1.0
161
161
  def counter_cache_column_name
162
162
  if self[:counter_cache] == true
163
- "#{inverse_class_name.demodulize.underscore.pluralize}_count"
163
+ "#{inverse || inverse_class_name.demodulize.underscore.pluralize}_count"
164
164
  else
165
165
  self[:counter_cache].to_s
166
166
  end
@@ -16,7 +16,7 @@ module Mongoid
16
16
  # @attribute [rw] _unloaded A criteria representing persisted docs.
17
17
  attr_accessor :_added, :_loaded, :_unloaded
18
18
 
19
- delegate :===, :is_a?, :kind_of?, to: []
19
+ delegate :is_a?, :kind_of?, to: []
20
20
 
21
21
  # Check if the enumerable is equal to the other object.
22
22
  #
@@ -33,6 +33,21 @@ module Mongoid
33
33
  entries == other.entries
34
34
  end
35
35
 
36
+ # Check equality of the enumerable against the provided object for case
37
+ # statements.
38
+ #
39
+ # @example Check case equality.
40
+ # enumerable === Array
41
+ #
42
+ # @param [ Object ] other The object to check.
43
+ #
44
+ # @return [ true, false ] If the objects are equal in a case.
45
+ #
46
+ # @since 3.1.4
47
+ def ===(other)
48
+ other.class == Class ? Array == other : self == other
49
+ end
50
+
36
51
  # Append a document to the enumerable.
37
52
  #
38
53
  # @example Append the document.
@@ -8,12 +8,37 @@ module Mongoid
8
8
 
9
9
  included do
10
10
  class_attribute :default_scoping
11
- class_attribute :scopes
12
- self.scopes = {}
11
+ class_attribute :_declared_scopes
12
+ self._declared_scopes = {}
13
13
  end
14
14
 
15
15
  module ClassMethods
16
16
 
17
+ # Returns a hash of all the scopes defined for this class, including
18
+ # scopes defined on ancestor classes.
19
+ #
20
+ # @example Get the defined scopes for a class
21
+ # class Band
22
+ # include Mongoid::Document
23
+ # field :active, type: Boolean
24
+ #
25
+ # scope :active, where(active: true)
26
+ # end
27
+ # Band.scopes
28
+ #
29
+ # @return [ Hash ] The scopes defined for this class
30
+ #
31
+ # @since 3.1.4
32
+ def scopes
33
+ defined_scopes = {}
34
+ ancestors.reverse.each do |klass|
35
+ if klass.respond_to?(:_declared_scopes)
36
+ defined_scopes.merge!(klass._declared_scopes)
37
+ end
38
+ end
39
+ defined_scopes.freeze
40
+ end
41
+
17
42
  # Add a default scope to the model. This scope will be applied to all
18
43
  # criteria unless #unscoped is specified.
19
44
  #
@@ -94,7 +119,7 @@ module Mongoid
94
119
  normalized = name.to_sym
95
120
  check_scope_validity(value)
96
121
  check_scope_name(normalized)
97
- scopes[normalized] = {
122
+ _declared_scopes[normalized] = {
98
123
  scope: strip_default_scope(value),
99
124
  extension: Module.new(&block)
100
125
  }
@@ -226,7 +251,7 @@ module Mongoid
226
251
  #
227
252
  # @since 2.1.0
228
253
  def check_scope_name(name)
229
- if scopes[name] || respond_to?(name, true)
254
+ if _declared_scopes[name] || respond_to?(name, true)
230
255
  if Mongoid.scope_overwrite_exception
231
256
  raise Errors::ScopeOverwrite.new(self.name, name)
232
257
  else
@@ -273,9 +298,9 @@ module Mongoid
273
298
  #
274
299
  # @since 3.0.0
275
300
  def define_scope_method(name)
276
- (class << self; self; end).class_eval <<-SCOPE
301
+ (class << self; self; end).class_eval <<-SCOPE, __FILE__, __LINE__ + 1
277
302
  def #{name}(*args)
278
- scoping = scopes[:#{name}]
303
+ scoping = _declared_scopes[:#{name}]
279
304
  scope, extension = scoping[:scope][*args], scoping[:extension]
280
305
  criteria = with_default_scope.merge(scope || all)
281
306
  criteria.extend(extension)
@@ -141,16 +141,6 @@ module Mongoid
141
141
  true
142
142
  end
143
143
 
144
- # Clear out all options set on a one-time basis.
145
- #
146
- # @example Clear out the options.
147
- # Threaded.clear_options!
148
- #
149
- # @since 2.3.0
150
- def clear_options!
151
- self.timeless = false
152
- end
153
-
154
144
  # Exit autosaving a document on the current thread.
155
145
  #
156
146
  # @example Exit autosave.
@@ -355,42 +345,6 @@ module Mongoid
355
345
  Thread.current["[mongoid]:scope-stack"] ||= {}
356
346
  end
357
347
 
358
- # Get the value of the one-off timeless call.
359
- #
360
- # @example Get the timeless value.
361
- # Threaded.timeless
362
- #
363
- # @return [ true, false ] The timeless setting.
364
- #
365
- # @since 2.3.0
366
- def timeless
367
- !!Thread.current["[mongoid]:timeless"]
368
- end
369
-
370
- # Set the value of the one-off timeless call.
371
- #
372
- # @example Set the timeless value.
373
- # Threaded.timeless = true
374
- #
375
- # @param [ true, false ] value The value.
376
- #
377
- # @since 2.3.0
378
- def timeless=(value)
379
- Thread.current["[mongoid]:timeless"] = value
380
- end
381
-
382
- # Is the current thread setting timestamps?
383
- #
384
- # @example Is the current thread timestamping?
385
- # Threaded.timestamping?
386
- #
387
- # @return [ true, false ] If timestamps can be applied.
388
- #
389
- # @since 2.3.0
390
- def timestamping?
391
- !timeless
392
- end
393
-
394
348
  # Is the document autosaved on the current thread?
395
349
  #
396
350
  # @example Is the document autosaved?
@@ -7,6 +7,23 @@ module Mongoid
7
7
  module Timeless
8
8
  extend ActiveSupport::Concern
9
9
 
10
+ included do
11
+ class_attribute :timestamping
12
+ self.timestamping = true
13
+ end
14
+
15
+ # Clears out the timeless option.
16
+ #
17
+ # @example Clear the timeless option.
18
+ # document.clear_timeless_option
19
+ #
20
+ # @return [ true ] True.
21
+ #
22
+ # @since 3.1.4
23
+ def clear_timeless_option
24
+ self.class.timestamping = true
25
+ end
26
+
10
27
  # Begin an execution that should skip timestamping.
11
28
  #
12
29
  # @example Save a document but don't timestamp.
@@ -16,21 +33,11 @@ module Mongoid
16
33
  #
17
34
  # @since 2.3.0
18
35
  def timeless
19
- Threaded.timeless = true
36
+ self.class.timestamping = false
20
37
  self
21
38
  end
22
39
 
23
- # Are we currently timestamping?
24
- #
25
- # @example Should timestamps be applied?
26
- # person.timestamping?
27
- #
28
- # @return [ true, false ] If the current thread is timestamping.
29
- #
30
- # @since 2.3.0
31
- def timestamping?
32
- Threaded.timestamping?
33
- end
40
+ private
34
41
 
35
42
  module ClassMethods
36
43
 
@@ -43,7 +50,7 @@ module Mongoid
43
50
  #
44
51
  # @since 2.3.0
45
52
  def timeless
46
- Threaded.timeless = true
53
+ self.timestamping = false
47
54
  self
48
55
  end
49
56
  end
@@ -105,7 +105,7 @@ module Mongoid
105
105
  # @since 2.4.10
106
106
  def create_criteria(base, document, attribute, value)
107
107
  criteria = scope(base.unscoped, document, attribute)
108
- criteria.selector.update(criterion(document, attribute, value))
108
+ criteria.selector.update(criterion(document, attribute, value.mongoize))
109
109
  criteria
110
110
  end
111
111
 
@@ -124,11 +124,13 @@ module Mongoid
124
124
  #
125
125
  # @since 2.3.0
126
126
  def criterion(document, attribute, value)
127
- if localized?(document, attribute)
128
- conditions = value.inject([]) { |acc, (k,v)| acc << { "#{attribute}.#{k}" => filter(v) } }
127
+ field = document.database_field_name(attribute)
128
+
129
+ if localized?(document, field)
130
+ conditions = value.inject([]) { |acc, (k,v)| acc << { "#{field}.#{k}" => filter(v) } }
129
131
  selector = { "$or" => conditions }
130
132
  else
131
- selector = { attribute => filter(value) }
133
+ selector = { field => filter(value) }
132
134
  end
133
135
 
134
136
  if document.persisted? && !document.embedded?
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid
3
- VERSION = "3.1.3"
3
+ VERSION = "3.1.4"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.3
4
+ version: 3.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Durran Jordan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-17 00:00:00.000000000 Z
11
+ date: 2013-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: 1.4.2
47
+ version: '1.4'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: 1.4.2
54
+ version: '1.4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: origin
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -124,7 +124,6 @@ files:
124
124
  - lib/mongoid/errors/eager_load.rb
125
125
  - lib/mongoid/errors/invalid_collection.rb
126
126
  - lib/mongoid/errors/invalid_config_option.rb
127
- - lib/mongoid/errors/invalid_database.rb
128
127
  - lib/mongoid/errors/invalid_field.rb
129
128
  - lib/mongoid/errors/invalid_field_option.rb
130
129
  - lib/mongoid/errors/invalid_find.rb
@@ -1,19 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid
3
- module Errors
4
-
5
- # Raised when the database connection has not been set up properly, either
6
- # by attempting to set an object on the db that is not a +Mongo::DB+, or
7
- # not setting anything at all.
8
- #
9
- # @example Create the error.
10
- # InvalidDatabase.new("Not a DB")
11
- class InvalidDatabase < MongoidError
12
- def initialize(database)
13
- super(
14
- compose_message("invalid_database", { name: database.class.name })
15
- )
16
- end
17
- end
18
- end
19
- end