mongoid 3.1.3 → 3.1.4

Sign up to get free protection for your applications and to get access to all the features.
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