mongoid 2.0.0.beta.5 → 2.0.0.beta.7
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.
- data/lib/mongoid.rb +10 -2
- data/lib/mongoid/associations.rb +82 -58
- data/lib/mongoid/associations/embeds_one.rb +6 -6
- data/lib/mongoid/associations/foreign_key.rb +35 -0
- data/lib/mongoid/associations/meta_data.rb +9 -0
- data/lib/mongoid/associations/options.rb +1 -1
- data/lib/mongoid/associations/proxy.rb +9 -0
- data/lib/mongoid/associations/{belongs_to_related.rb → referenced_in.rb} +6 -5
- data/lib/mongoid/associations/{has_many_related.rb → references_many.rb} +69 -26
- data/lib/mongoid/associations/references_many_as_array.rb +78 -0
- data/lib/mongoid/associations/{has_one_related.rb → references_one.rb} +16 -2
- data/lib/mongoid/atomicity.rb +42 -0
- data/lib/mongoid/attributes.rb +148 -146
- data/lib/mongoid/callbacks.rb +5 -1
- data/lib/mongoid/collections.rb +31 -1
- data/lib/mongoid/components.rb +4 -1
- data/lib/mongoid/config.rb +2 -1
- data/lib/mongoid/criteria.rb +9 -0
- data/lib/mongoid/dirty.rb +211 -212
- data/lib/mongoid/document.rb +126 -185
- data/lib/mongoid/extensions.rb +5 -0
- data/lib/mongoid/extensions/array/conversions.rb +3 -5
- data/lib/mongoid/extensions/hash/conversions.rb +19 -22
- data/lib/mongoid/extensions/object/conversions.rb +3 -5
- data/lib/mongoid/extensions/set/conversions.rb +20 -0
- data/lib/mongoid/field.rb +11 -0
- data/lib/mongoid/finders.rb +8 -0
- data/lib/mongoid/hierarchy.rb +76 -0
- data/lib/mongoid/identity.rb +37 -29
- data/lib/mongoid/paths.rb +46 -47
- data/lib/mongoid/persistence.rb +111 -113
- data/lib/mongoid/persistence/insert.rb +1 -1
- data/lib/mongoid/persistence/insert_embedded.rb +10 -5
- data/lib/mongoid/persistence/remove_all.rb +3 -2
- data/lib/mongoid/persistence/update.rb +8 -3
- data/lib/mongoid/railtie.rb +3 -0
- data/lib/mongoid/railties/database.rake +33 -18
- data/lib/mongoid/timestamps.rb +9 -12
- data/lib/mongoid/validations/uniqueness.rb +16 -4
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +10 -11
- data/lib/rails/generators/mongoid/config/config_generator.rb +0 -16
- metadata +64 -24
data/lib/mongoid/callbacks.rb
CHANGED
data/lib/mongoid/collections.rb
CHANGED
@@ -7,7 +7,8 @@ module Mongoid #:nodoc
|
|
7
7
|
included do
|
8
8
|
cattr_accessor :_collection, :collection_name
|
9
9
|
self.collection_name = self.name.collectionize
|
10
|
-
|
10
|
+
|
11
|
+
delegate :collection, :db, :to => "self.class"
|
11
12
|
end
|
12
13
|
|
13
14
|
module ClassMethods #:nodoc:
|
@@ -22,6 +23,35 @@ module Mongoid #:nodoc
|
|
22
23
|
add_indexes; self._collection
|
23
24
|
end
|
24
25
|
|
26
|
+
# Return the database associated with this collection.
|
27
|
+
#
|
28
|
+
# Example:
|
29
|
+
#
|
30
|
+
# <tt>Person.db</tt>
|
31
|
+
def db
|
32
|
+
collection.db
|
33
|
+
end
|
34
|
+
|
35
|
+
# Convenience method for getting index information from the collection.
|
36
|
+
#
|
37
|
+
# Example:
|
38
|
+
#
|
39
|
+
# <tt>Person.index_information</tt>
|
40
|
+
def index_information
|
41
|
+
collection.index_information
|
42
|
+
end
|
43
|
+
|
44
|
+
# The MongoDB logger is not exposed through the driver to be changed
|
45
|
+
# after initialization of the connection, this is a hacky way around that
|
46
|
+
# if logging needs to be changed at runtime.
|
47
|
+
#
|
48
|
+
# Example:
|
49
|
+
#
|
50
|
+
# <tt>Person.logger = Logger.new($stdout)</tt>
|
51
|
+
def logger=(logger)
|
52
|
+
db.connection.instance_variable_set(:@logger, logger)
|
53
|
+
end
|
54
|
+
|
25
55
|
# Macro for setting the collection name to store in.
|
26
56
|
#
|
27
57
|
# Example:
|
data/lib/mongoid/components.rb
CHANGED
@@ -9,13 +9,15 @@ module Mongoid #:nodoc
|
|
9
9
|
include ActiveModel::Naming
|
10
10
|
include ActiveModel::Serialization
|
11
11
|
include ActiveModel::Serializers::JSON
|
12
|
+
include ActiveModel::Serializers::Xml
|
12
13
|
include Mongoid::Associations
|
14
|
+
include Mongoid::Atomicity
|
13
15
|
include Mongoid::Attributes
|
14
|
-
include Mongoid::Callbacks
|
15
16
|
include Mongoid::Collections
|
16
17
|
include Mongoid::Dirty
|
17
18
|
include Mongoid::Extras
|
18
19
|
include Mongoid::Fields
|
20
|
+
include Mongoid::Hierarchy
|
19
21
|
include Mongoid::Indexes
|
20
22
|
include Mongoid::Matchers
|
21
23
|
include Mongoid::Memoization
|
@@ -24,6 +26,7 @@ module Mongoid #:nodoc
|
|
24
26
|
include Mongoid::Persistence
|
25
27
|
include Mongoid::State
|
26
28
|
include Mongoid::Validations
|
29
|
+
include Mongoid::Callbacks
|
27
30
|
extend ActiveModel::Translation
|
28
31
|
extend Mongoid::Finders
|
29
32
|
extend Mongoid::NamedScope
|
data/lib/mongoid/config.rb
CHANGED
@@ -193,10 +193,11 @@ module Mongoid #:nodoc
|
|
193
193
|
name = settings["database"] || mongo_uri.path.to_s.sub("/", "")
|
194
194
|
host = settings["host"] || mongo_uri.host || "localhost"
|
195
195
|
port = settings["port"] || mongo_uri.port || 27017
|
196
|
+
pool_size = settings["pool_size"] || 1
|
196
197
|
username = settings["username"] || mongo_uri.user
|
197
198
|
password = settings["password"] || mongo_uri.password
|
198
199
|
|
199
|
-
connection = Mongo::Connection.new(host, port, :logger => logger)
|
200
|
+
connection = Mongo::Connection.new(host, port, :logger => logger, :pool_size => pool_size)
|
200
201
|
if username || password
|
201
202
|
connection.add_auth(name, username, password)
|
202
203
|
connection.apply_saved_authentication
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -82,6 +82,15 @@ module Mongoid #:nodoc:
|
|
82
82
|
self
|
83
83
|
end
|
84
84
|
|
85
|
+
# Return true if the criteria has some Document or not
|
86
|
+
#
|
87
|
+
# Example:
|
88
|
+
#
|
89
|
+
# <tt>criteria.exists?</tt>
|
90
|
+
def exists?
|
91
|
+
context.count > 0
|
92
|
+
end
|
93
|
+
|
85
94
|
# Merges the supplied argument hash into a single criteria
|
86
95
|
#
|
87
96
|
# Options:
|
data/lib/mongoid/dirty.rb
CHANGED
@@ -2,231 +2,230 @@
|
|
2
2
|
module Mongoid #:nodoc:
|
3
3
|
module Dirty #:nodoc:
|
4
4
|
extend ActiveSupport::Concern
|
5
|
-
module InstanceMethods #:nodoc:
|
6
|
-
# Gets the changes for a specific field.
|
7
|
-
#
|
8
|
-
# Example:
|
9
|
-
#
|
10
|
-
# person = Person.new(:title => "Sir")
|
11
|
-
# person.title = "Madam"
|
12
|
-
# person.attribute_change("title") # [ "Sir", "Madam" ]
|
13
|
-
#
|
14
|
-
# Returns:
|
15
|
-
#
|
16
|
-
# An +Array+ containing the old and new values.
|
17
|
-
def attribute_change(name)
|
18
|
-
modifications[name]
|
19
|
-
end
|
20
5
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
6
|
+
# Gets the changes for a specific field.
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
#
|
10
|
+
# person = Person.new(:title => "Sir")
|
11
|
+
# person.title = "Madam"
|
12
|
+
# person.attribute_change("title") # [ "Sir", "Madam" ]
|
13
|
+
#
|
14
|
+
# Returns:
|
15
|
+
#
|
16
|
+
# An +Array+ containing the old and new values.
|
17
|
+
def attribute_change(name)
|
18
|
+
modifications[name]
|
19
|
+
end
|
35
20
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
21
|
+
# Determines if a specific field has chaged.
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
#
|
25
|
+
# person = Person.new(:title => "Sir")
|
26
|
+
# person.title = "Madam"
|
27
|
+
# person.attribute_changed?("title") # true
|
28
|
+
#
|
29
|
+
# Returns:
|
30
|
+
#
|
31
|
+
# +true+ if changed, +false+ if not.
|
32
|
+
def attribute_changed?(name)
|
33
|
+
modifications.include?(name)
|
34
|
+
end
|
51
35
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
36
|
+
# Gets the old value for a specific field.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
#
|
40
|
+
# person = Person.new(:title => "Sir")
|
41
|
+
# person.title = "Madam"
|
42
|
+
# person.attribute_was("title") # "Sir"
|
43
|
+
#
|
44
|
+
# Returns:
|
45
|
+
#
|
46
|
+
# The old field value.
|
47
|
+
def attribute_was(name)
|
48
|
+
change = modifications[name]
|
49
|
+
change ? change[0] : nil
|
50
|
+
end
|
66
51
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
52
|
+
# Gets the names of all the fields that have changed in the document.
|
53
|
+
#
|
54
|
+
# Example:
|
55
|
+
#
|
56
|
+
# person = Person.new(:title => "Sir")
|
57
|
+
# person.title = "Madam"
|
58
|
+
# person.changed # returns [ "title" ]
|
59
|
+
#
|
60
|
+
# Returns:
|
61
|
+
#
|
62
|
+
# An +Array+ of changed field names.
|
63
|
+
def changed
|
64
|
+
modifications.keys
|
65
|
+
end
|
81
66
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
modifications
|
97
|
-
end
|
67
|
+
# Alerts to whether the document has been modified or not.
|
68
|
+
#
|
69
|
+
# Example:
|
70
|
+
#
|
71
|
+
# person = Person.new(:title => "Sir")
|
72
|
+
# person.title = "Madam"
|
73
|
+
# person.changed? # returns true
|
74
|
+
#
|
75
|
+
# Returns:
|
76
|
+
#
|
77
|
+
# +true+ if changed, +false+ if not.
|
78
|
+
def changed?
|
79
|
+
!modifications.empty?
|
80
|
+
end
|
98
81
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
82
|
+
# Gets all the modifications that have happened to the object as a +Hash+
|
83
|
+
# with the keys being the names of the fields, and the values being an
|
84
|
+
# +Array+ with the old value and new value.
|
85
|
+
#
|
86
|
+
# Example:
|
87
|
+
#
|
88
|
+
# person = Person.new(:title => "Sir")
|
89
|
+
# person.title = "Madam"
|
90
|
+
# person.changes # returns { "title" => [ "Sir", "Madam" ] }
|
91
|
+
#
|
92
|
+
# Returns:
|
93
|
+
#
|
94
|
+
# A +Hash+ of changes.
|
95
|
+
def changes
|
96
|
+
modifications
|
97
|
+
end
|
108
98
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
# Returns:
|
119
|
-
#
|
120
|
-
# A +Hash+ of new values.
|
121
|
-
def setters
|
122
|
-
modifications.inject({}) do |sets, (field, changes)|
|
123
|
-
key = embedded? ? "#{_position}.#{field}" : field
|
124
|
-
sets[key] = changes[1]; sets
|
125
|
-
end
|
126
|
-
end
|
99
|
+
# Call this method after save, so the changes can be properly switched.
|
100
|
+
#
|
101
|
+
# Example:
|
102
|
+
#
|
103
|
+
# <tt>person.move_changes</tt>
|
104
|
+
def move_changes
|
105
|
+
@previous_modifications = modifications.dup
|
106
|
+
@modifications = {}
|
107
|
+
end
|
127
108
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
109
|
+
# Gets all the new values for each of the changed fields, to be passed to
|
110
|
+
# a MongoDB $set modifier.
|
111
|
+
#
|
112
|
+
# Example:
|
113
|
+
#
|
114
|
+
# person = Person.new(:title => "Sir")
|
115
|
+
# person.title = "Madam"
|
116
|
+
# person.setters # returns { "title" => "Madam" }
|
117
|
+
#
|
118
|
+
# Returns:
|
119
|
+
#
|
120
|
+
# A +Hash+ of new values.
|
121
|
+
def setters
|
122
|
+
modifications.inject({}) do |sets, (field, changes)|
|
123
|
+
key = embedded? ? "#{_position}.#{field}" : field
|
124
|
+
sets[key] = changes[1]; sets
|
143
125
|
end
|
126
|
+
end
|
144
127
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
modifications.delete(name)
|
162
|
-
end
|
163
|
-
end
|
128
|
+
# Gets all the modifications that have happened to the object before the
|
129
|
+
# object was saved.
|
130
|
+
#
|
131
|
+
# Example:
|
132
|
+
#
|
133
|
+
# person = Person.new(:title => "Sir")
|
134
|
+
# person.title = "Madam"
|
135
|
+
# person.save!
|
136
|
+
# person.previous_changes # returns { "title" => [ "Sir", "Madam" ] }
|
137
|
+
#
|
138
|
+
# Returns:
|
139
|
+
#
|
140
|
+
# A +Hash+ of changes before save.
|
141
|
+
def previous_changes
|
142
|
+
@previous_modifications
|
143
|
+
end
|
164
144
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
145
|
+
# Resets a changed field back to its old value.
|
146
|
+
#
|
147
|
+
# Example:
|
148
|
+
#
|
149
|
+
# person = Person.new(:title => "Sir")
|
150
|
+
# person.title = "Madam"
|
151
|
+
# person.reset_attribute!("title")
|
152
|
+
# person.title # "Sir"
|
153
|
+
#
|
154
|
+
# Returns:
|
155
|
+
#
|
156
|
+
# The old field value.
|
157
|
+
def reset_attribute!(name)
|
158
|
+
value = attribute_was(name)
|
159
|
+
if value
|
160
|
+
@attributes[name] = value
|
161
|
+
modifications.delete(name)
|
175
162
|
end
|
163
|
+
end
|
176
164
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
165
|
+
# Sets up the modifications hash. This occurs just after the document is
|
166
|
+
# instantiated.
|
167
|
+
#
|
168
|
+
# Example:
|
169
|
+
#
|
170
|
+
# <tt>document.setup_notifications</tt>
|
171
|
+
def setup_modifications
|
172
|
+
@accessed ||= {}
|
173
|
+
@modifications ||= {}
|
174
|
+
@previous_modifications ||= {}
|
175
|
+
end
|
187
176
|
|
188
|
-
|
177
|
+
# Reset all modifications for the document. This will wipe all the marked
|
178
|
+
# changes, but not reset the values.
|
179
|
+
#
|
180
|
+
# Example:
|
181
|
+
#
|
182
|
+
# <tt>document.reset_modifications</tt>
|
183
|
+
def reset_modifications
|
184
|
+
@accessed = {}
|
185
|
+
@modifications = {}
|
186
|
+
end
|
189
187
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
188
|
+
protected
|
189
|
+
|
190
|
+
# Audit the original value for a field that can be modified in place.
|
191
|
+
#
|
192
|
+
# Example:
|
193
|
+
#
|
194
|
+
# <tt>person.accessed("aliases", [ "007" ])</tt>
|
195
|
+
def accessed(name, value)
|
196
|
+
@accessed ||= {}
|
197
|
+
@accessed[name] = value.dup if (value.is_a?(Array) || value.is_a?(Hash)) && !@accessed.has_key?(name)
|
198
|
+
value
|
199
|
+
end
|
200
200
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
201
|
+
# Get all normal modifications plus in place potential changes.
|
202
|
+
#
|
203
|
+
# Example:
|
204
|
+
#
|
205
|
+
# <tt>person.modifications</tt>
|
206
|
+
#
|
207
|
+
# Returns:
|
208
|
+
#
|
209
|
+
# All changes to the document.
|
210
|
+
def modifications
|
211
|
+
@accessed.each_pair do |field, value|
|
212
|
+
current = @attributes[field]
|
213
|
+
@modifications[field] = [ value, current ] if current != value
|
214
|
+
end
|
215
|
+
@accessed.clear
|
216
|
+
@modifications
|
217
|
+
end
|
218
218
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
end
|
219
|
+
# Audit the change of a field's value.
|
220
|
+
#
|
221
|
+
# Example:
|
222
|
+
#
|
223
|
+
# <tt>person.modify("name", "Jack", "John")</tt>
|
224
|
+
def modify(name, old_value, new_value)
|
225
|
+
@attributes[name] = new_value
|
226
|
+
if @modifications && (old_value != new_value)
|
227
|
+
original = @modifications[name].first if @modifications[name]
|
228
|
+
@modifications[name] = [ (original || old_value), new_value ]
|
230
229
|
end
|
231
230
|
end
|
232
231
|
|
@@ -243,10 +242,10 @@ module Mongoid #:nodoc:
|
|
243
242
|
# person.title_was # "Sir"
|
244
243
|
# person.reset_title!
|
245
244
|
def add_dirty_methods(name)
|
246
|
-
define_method("#{name}_change") { attribute_change(name) }
|
247
|
-
define_method("#{name}_changed?") { attribute_changed?(name) }
|
248
|
-
define_method("#{name}_was") { attribute_was(name) }
|
249
|
-
define_method("reset_#{name}!") { reset_attribute!(name) }
|
245
|
+
define_method("#{name}_change") { attribute_change(name) } unless instance_methods.include?("#{name}_change")
|
246
|
+
define_method("#{name}_changed?") { attribute_changed?(name) } unless instance_methods.include?("#{name}_changed?")
|
247
|
+
define_method("#{name}_was") { attribute_was(name) } unless instance_methods.include?("#{name}_was")
|
248
|
+
define_method("reset_#{name}!") { reset_attribute!(name) } unless instance_methods.include?("reset_#{name}!")
|
250
249
|
end
|
251
250
|
end
|
252
251
|
end
|