mongoid 0.4.5 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.watchr +1 -1
- data/README.textile +5 -0
- data/VERSION +1 -1
- data/lib/mongoid.rb +3 -1
- data/lib/mongoid/associations.rb +84 -1
- data/lib/mongoid/associations/has_many_association.rb +8 -4
- data/lib/mongoid/commands.rb +4 -4
- data/lib/mongoid/criteria.rb +57 -5
- data/lib/mongoid/document.rb +83 -125
- data/lib/mongoid/extensions.rb +16 -1
- data/lib/mongoid/extensions/array/conversions.rb +1 -1
- data/lib/mongoid/extensions/array/parentization.rb +3 -3
- data/lib/mongoid/extensions/hash/accessors.rb +21 -0
- data/lib/mongoid/extensions/object/parentization.rb +4 -2
- data/lib/mongoid/extensions/string/inflections.rb +14 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +14 -0
- data/lib/mongoid/timestamps.rb +30 -0
- data/mongoid.gemspec +18 -4
- data/spec/integration/mongoid/document_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -4
- data/spec/unit/mongoid/associations/has_many_association_spec.rb +1 -1
- data/spec/unit/mongoid/associations_spec.rb +125 -0
- data/spec/unit/mongoid/criteria_spec.rb +154 -0
- data/spec/unit/mongoid/document_spec.rb +110 -150
- data/spec/unit/mongoid/extensions/array/parentization_spec.rb +4 -2
- data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +87 -0
- data/spec/unit/mongoid/extensions/object/parentization_spec.rb +2 -2
- data/spec/unit/mongoid/extensions/string/inflections_spec.rb +45 -0
- data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +45 -0
- data/spec/unit/mongoid/timestamps_spec.rb +19 -0
- metadata +16 -2
data/.watchr
CHANGED
data/README.textile
CHANGED
@@ -18,6 +18,11 @@
|
|
18
18
|
Mongoid is developed against Ruby 1.8.6, 1.8.7, 1.9.1, 1.9.2
|
19
19
|
</p>
|
20
20
|
|
21
|
+
<p>
|
22
|
+
Note API changes will be frequent until the 1.0 release, and do not expect
|
23
|
+
the gem to be of full production quality until that point.
|
24
|
+
</p>
|
25
|
+
|
21
26
|
<h2>Mongoid in Action</h2>
|
22
27
|
|
23
28
|
Initialize Mongoid:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.7
|
data/lib/mongoid.rb
CHANGED
@@ -25,10 +25,11 @@ gem "mongo", "0.15.1"
|
|
25
25
|
gem "durran-validatable", "1.7.5"
|
26
26
|
gem "will_paginate", "2.3.11"
|
27
27
|
|
28
|
+
require "delegate"
|
29
|
+
require "observer"
|
28
30
|
require "validatable"
|
29
31
|
require "active_support/callbacks"
|
30
32
|
require "active_support/core_ext"
|
31
|
-
require "delegate"
|
32
33
|
require "will_paginate/collection"
|
33
34
|
require "mongo"
|
34
35
|
require "mongoid/associations"
|
@@ -37,6 +38,7 @@ require "mongoid/criteria"
|
|
37
38
|
require "mongoid/extensions"
|
38
39
|
require "mongoid/field"
|
39
40
|
require "mongoid/document"
|
41
|
+
require "mongoid/timestamps"
|
40
42
|
|
41
43
|
module Mongoid
|
42
44
|
|
data/lib/mongoid/associations.rb
CHANGED
@@ -2,4 +2,87 @@ require "mongoid/associations/decorator"
|
|
2
2
|
require "mongoid/associations/factory"
|
3
3
|
require "mongoid/associations/belongs_to_association"
|
4
4
|
require "mongoid/associations/has_many_association"
|
5
|
-
require "mongoid/associations/has_one_association"
|
5
|
+
require "mongoid/associations/has_one_association"
|
6
|
+
|
7
|
+
module Mongoid # :nodoc:
|
8
|
+
module Associations
|
9
|
+
|
10
|
+
# Adds the association back to the parent document. This macro is
|
11
|
+
# necessary to set the references from the child back to the parent
|
12
|
+
# document. If a child does not define this association calling
|
13
|
+
# persistence methods on the child object will cause a save to fail.
|
14
|
+
#
|
15
|
+
# Options:
|
16
|
+
#
|
17
|
+
# association_name: A +Symbol+ that matches the name of the parent class.
|
18
|
+
#
|
19
|
+
# Example:
|
20
|
+
#
|
21
|
+
# class Person < Mongoid::Document
|
22
|
+
# has_many :addresses
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# class Address < Mongoid::Document
|
26
|
+
# belongs_to :person
|
27
|
+
# end
|
28
|
+
def belongs_to(association_name)
|
29
|
+
@embedded = true
|
30
|
+
add_association(:belongs_to, association_name.to_s.classify, association_name)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Adds the association from a parent document to its children. The name
|
34
|
+
# of the association needs to be a pluralized form of the child class
|
35
|
+
# name.
|
36
|
+
#
|
37
|
+
# Options:
|
38
|
+
#
|
39
|
+
# association_name: A +Symbol+ that is the plural child class name.
|
40
|
+
#
|
41
|
+
# Example:
|
42
|
+
#
|
43
|
+
# class Person < Mongoid::Document
|
44
|
+
# has_many :addresses
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# class Address < Mongoid::Document
|
48
|
+
# belongs_to :person
|
49
|
+
# end
|
50
|
+
def has_many(association_name)
|
51
|
+
add_association(:has_many, association_name.to_s.classify, association_name)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Adds the association from a parent document to its child. The name
|
55
|
+
# of the association needs to be a singular form of the child class
|
56
|
+
# name.
|
57
|
+
#
|
58
|
+
# Options:
|
59
|
+
#
|
60
|
+
# association_name: A +Symbol+ that is the plural child class name.
|
61
|
+
#
|
62
|
+
# Example:
|
63
|
+
#
|
64
|
+
# class Person < Mongoid::Document
|
65
|
+
# has_many :addresses
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# class Address < Mongoid::Document
|
69
|
+
# belongs_to :person
|
70
|
+
# end
|
71
|
+
def has_one(association_name)
|
72
|
+
add_association(:has_one, association_name.to_s.titleize, association_name)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
# Adds the association to the associations hash with the type as the key,
|
77
|
+
# then adds the accessors for the association.
|
78
|
+
def add_association(type, class_name, name)
|
79
|
+
define_method(name) do
|
80
|
+
Associations::Factory.create(type, name, self)
|
81
|
+
end
|
82
|
+
define_method("#{name}=") do |object|
|
83
|
+
object.parentize(self, name)
|
84
|
+
@attributes[name] = object.mongoidize
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -2,10 +2,12 @@ module Mongoid #:nodoc:
|
|
2
2
|
module Associations #:nodoc:
|
3
3
|
class HasManyAssociation < DelegateClass(Array) #:nodoc:
|
4
4
|
|
5
|
+
attr_accessor :association_name
|
6
|
+
|
5
7
|
# Appends the object to the +Array+, setting its parent in
|
6
8
|
# the process.
|
7
9
|
def <<(object)
|
8
|
-
object.parentize(@parent)
|
10
|
+
object.parentize(@parent, @association_name)
|
9
11
|
@documents << object
|
10
12
|
end
|
11
13
|
|
@@ -28,6 +30,7 @@ module Mongoid #:nodoc:
|
|
28
30
|
# Returns the newly created object.
|
29
31
|
def build(attributes)
|
30
32
|
object = @klass.new(attributes)
|
33
|
+
object.parentize(@parent, @association_name)
|
31
34
|
push(object)
|
32
35
|
object
|
33
36
|
end
|
@@ -49,11 +52,12 @@ module Mongoid #:nodoc:
|
|
49
52
|
# essentially a proxy to an array itself.
|
50
53
|
def initialize(association_name, document)
|
51
54
|
@parent = document
|
52
|
-
@
|
53
|
-
|
55
|
+
@association_name = association_name
|
56
|
+
@klass = @association_name.to_s.classify.constantize
|
57
|
+
attributes = document.attributes[@association_name]
|
54
58
|
@documents = attributes ? attributes.collect do |attribute|
|
55
59
|
child = @klass.new(attribute)
|
56
|
-
child.parent
|
60
|
+
child.parentize(@parent, @association_name)
|
57
61
|
child
|
58
62
|
end : []
|
59
63
|
super(@documents)
|
data/lib/mongoid/commands.rb
CHANGED
@@ -57,15 +57,15 @@ module Mongoid #:nodoc:
|
|
57
57
|
|
58
58
|
# Update the attributes of the +Document+. Will call save after the
|
59
59
|
# attributes have been updated.
|
60
|
-
def update_attributes(
|
61
|
-
|
60
|
+
def update_attributes(attrs = {})
|
61
|
+
write_attributes(attrs); save
|
62
62
|
end
|
63
63
|
|
64
64
|
# Update the attributes of the +Document+. Will call save! after the
|
65
65
|
# attributes have been updated, causing a +ValidationError+ if the
|
66
66
|
# +Document+ failed validation.
|
67
|
-
def update_attributes!(
|
68
|
-
|
67
|
+
def update_attributes!(attrs = {})
|
68
|
+
write_attributes(attrs); save!
|
69
69
|
end
|
70
70
|
|
71
71
|
end
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -14,8 +14,23 @@ module Mongoid #:nodoc:
|
|
14
14
|
#
|
15
15
|
# <tt>criteria.execute</tt>
|
16
16
|
class Criteria
|
17
|
+
attr_accessor :klass
|
17
18
|
attr_reader :selector, :options, :type
|
18
19
|
|
20
|
+
AGGREGATE_REDUCE = "function(obj, prev) { prev.count++; }"
|
21
|
+
# Aggregate the criteria. This will take the internally built selector and options
|
22
|
+
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
23
|
+
# collection itself will be retrieved from the class provided, and once the
|
24
|
+
# query has returned it will provided a grouping of keys with counts.
|
25
|
+
#
|
26
|
+
# Example:
|
27
|
+
#
|
28
|
+
# <tt>criteria.select(:field1).where(:field1 => "Title").aggregate(Person)</tt>
|
29
|
+
def aggregate(klass = nil)
|
30
|
+
@klass = klass if klass
|
31
|
+
@klass.collection.group(@options[:fields], @selector, { :count => 0 }, AGGREGATE_REDUCE)
|
32
|
+
end
|
33
|
+
|
19
34
|
# Adds a criterion to the +Criteria+ that specifies values that must all
|
20
35
|
# be matched in order to return results. Similar to an "in" clause but the
|
21
36
|
# underlying conditional logic is an "AND" and not an "OR". The MongoDB
|
@@ -67,9 +82,10 @@ module Mongoid #:nodoc:
|
|
67
82
|
#
|
68
83
|
# If this is a +Criteria+ to find multiple results, will return an +Array+ of
|
69
84
|
# objects of the type of class provided.
|
70
|
-
def execute(klass)
|
71
|
-
|
72
|
-
return klass.collection.
|
85
|
+
def execute(klass = nil)
|
86
|
+
@klass = klass if klass
|
87
|
+
return @klass.new(klass.collection.find_one(@selector, @options)) if type == :first
|
88
|
+
return @klass.collection.find(@selector, @options).collect { |doc| @klass.new(doc) }
|
73
89
|
end
|
74
90
|
|
75
91
|
# Adds a criterion to the +Criteria+ that specifies additional options
|
@@ -88,6 +104,27 @@ module Mongoid #:nodoc:
|
|
88
104
|
@options = extras; self
|
89
105
|
end
|
90
106
|
|
107
|
+
GROUP_REDUCE = "function(obj, prev) { prev.group.push(obj); }"
|
108
|
+
# Groups the criteria. This will take the internally built selector and options
|
109
|
+
# and pass them on to the Ruby driver's +group()+ method on the collection. The
|
110
|
+
# collection itself will be retrieved from the class provided, and once the
|
111
|
+
# query has returned it will provided a grouping of keys with objects.
|
112
|
+
#
|
113
|
+
# Example:
|
114
|
+
#
|
115
|
+
# <tt>criteria.select(:field1).where(:field1 => "Title").group(Person)</tt>
|
116
|
+
def group(klass = nil)
|
117
|
+
@klass = klass if klass
|
118
|
+
@klass.collection.group(
|
119
|
+
@options[:fields],
|
120
|
+
@selector,
|
121
|
+
{ :group => [] },
|
122
|
+
GROUP_REDUCE
|
123
|
+
).collect do |docs|
|
124
|
+
docs["group"] = docs["group"].collect { |attrs| @klass.new(attrs) }; docs
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
91
128
|
# Adds a criterion to the +Criteria+ that specifies values where any can
|
92
129
|
# be matched in order to return results. This is similar to an SQL "IN"
|
93
130
|
# clause. The MongoDB conditional operator that will be used is "$in".
|
@@ -129,8 +166,9 @@ module Mongoid #:nodoc:
|
|
129
166
|
# Options:
|
130
167
|
#
|
131
168
|
# type: One of :all, :first:, or :last
|
132
|
-
|
133
|
-
|
169
|
+
# klass: The class to execute on.
|
170
|
+
def initialize(type, klass = nil)
|
171
|
+
@selector, @options, @type, @klass = {}, {}, type, klass
|
134
172
|
end
|
135
173
|
|
136
174
|
# Adds a criterion to the +Criteria+ that specifies the maximum number of
|
@@ -170,6 +208,14 @@ module Mongoid #:nodoc:
|
|
170
208
|
exclusions.each { |key, value| @selector[key] = { "$nin" => value } }; self
|
171
209
|
end
|
172
210
|
|
211
|
+
# Returns the offset option. If a per_page option is in the list then it
|
212
|
+
# will replace it with a skip parameter and return the same value. Defaults
|
213
|
+
# to 20 if nothing was provided.
|
214
|
+
def offset
|
215
|
+
offset = @options.delete(:per_page) || 20
|
216
|
+
@options[:skip] ||= offset
|
217
|
+
end
|
218
|
+
|
173
219
|
# Adds a criterion to the +Criteria+ that specifies the sort order of
|
174
220
|
# the returned documents in the database. Similar to a SQL "ORDER BY".
|
175
221
|
#
|
@@ -186,6 +232,12 @@ module Mongoid #:nodoc:
|
|
186
232
|
@options[:sort] = params; self
|
187
233
|
end
|
188
234
|
|
235
|
+
# Either returns the page option and removes it from the options, or
|
236
|
+
# returns a default value of 1.
|
237
|
+
def page
|
238
|
+
@options.delete(:page) || 1
|
239
|
+
end
|
240
|
+
|
189
241
|
# Adds a criterion to the +Criteria+ that specifies the fields that will
|
190
242
|
# get returned from the Document. Used mainly for list views that do not
|
191
243
|
# require all fields to be present. This is similar to SQL "SELECT" values.
|
data/lib/mongoid/document.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
module Mongoid #:nodoc:
|
2
2
|
class Document
|
3
3
|
include ActiveSupport::Callbacks
|
4
|
-
include Validatable
|
5
|
-
|
4
|
+
include Commands, Observable, Validatable
|
5
|
+
extend Associations
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
attr_accessor :attributes, :parent
|
7
|
+
attr_accessor :association_name, :parent
|
8
|
+
attr_reader :attributes
|
11
9
|
|
12
10
|
define_callbacks \
|
13
11
|
:after_create,
|
@@ -19,37 +17,22 @@ module Mongoid #:nodoc:
|
|
19
17
|
|
20
18
|
class << self
|
21
19
|
|
22
|
-
#
|
23
|
-
# selector that is provided.
|
24
|
-
def aggregate(fields, params = {})
|
25
|
-
selector = params[:conditions]
|
26
|
-
collection.group(fields, selector, { :count => 0 }, AGGREGATE_REDUCE)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Adds the association back to the parent document. This macro is
|
30
|
-
# necessary to set the references from the child back to the parent
|
31
|
-
# document. If a child does not define this association calling
|
32
|
-
# persistence methods on the child object will cause a save to fail.
|
20
|
+
# Find +Documents+ given the conditions.
|
33
21
|
#
|
34
22
|
# Options:
|
35
23
|
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
# Example:
|
39
|
-
#
|
40
|
-
# class Person < Mongoid::Document
|
41
|
-
# has_many :addresses
|
42
|
-
# end
|
24
|
+
# args: A +Hash+ with a conditions key and other options
|
43
25
|
#
|
44
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
def belongs_to(association_name)
|
48
|
-
@embedded = true
|
49
|
-
add_association(:belongs_to, association_name.to_s.classify, association_name)
|
26
|
+
# <tt>Person.all(:conditions => { :attribute => "value" })</tt>
|
27
|
+
def all(*args)
|
28
|
+
find(:all, *args)
|
50
29
|
end
|
51
30
|
|
52
|
-
#
|
31
|
+
# Returns the collection associated with this +Document+. If the
|
32
|
+
# document is embedded, there will be no collection associated
|
33
|
+
# with it.
|
34
|
+
#
|
35
|
+
# Returns: <tt>Mongo::Collection</tt>
|
53
36
|
def collection
|
54
37
|
return nil if @embedded
|
55
38
|
@collection_name = self.to_s.demodulize.tableize
|
@@ -97,85 +80,57 @@ module Mongoid #:nodoc:
|
|
97
80
|
Criteria.translate(*args).execute(self)
|
98
81
|
end
|
99
82
|
|
100
|
-
# Find
|
101
|
-
#
|
83
|
+
# Find the first +Document+ given the conditions.
|
84
|
+
#
|
85
|
+
# Options:
|
86
|
+
#
|
87
|
+
# args: A +Hash+ with a conditions key and other options
|
88
|
+
#
|
89
|
+
# <tt>Person.first(:conditions => { :attribute => "value" })</tt>
|
102
90
|
def first(*args)
|
103
91
|
find(:first, *args)
|
104
92
|
end
|
105
93
|
|
106
|
-
#
|
107
|
-
#
|
108
|
-
def
|
109
|
-
|
94
|
+
# Adds an index on the field specified. Options can be :unique => true or
|
95
|
+
# :unique => false. It will default to the latter.
|
96
|
+
def index(name, options = { :unique => false })
|
97
|
+
collection.create_index(name, options)
|
110
98
|
end
|
111
99
|
|
112
|
-
#
|
113
|
-
#
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
100
|
+
# Defines the field that will be used for the id of this +Document+. This
|
101
|
+
# set the id of this +Document+ before save to a parameterized version of
|
102
|
+
# the field that was supplied. This is good for use for readable URLS in
|
103
|
+
# web applications and *MUST* be defined on documents that are embedded
|
104
|
+
# in order for proper updates in has_may associations.
|
105
|
+
def key(*fields)
|
106
|
+
@primary_key = fields
|
107
|
+
before_save :generate_key
|
119
108
|
end
|
120
109
|
|
121
|
-
#
|
122
|
-
|
123
|
-
|
110
|
+
# Returns the primary key field of the +Document+
|
111
|
+
def primary_key
|
112
|
+
@primary_key
|
113
|
+
end
|
114
|
+
|
115
|
+
# Find all documents in paginated fashion given the supplied arguments.
|
116
|
+
# If no parameters are passed just default to offset 0 and limit 20.
|
124
117
|
#
|
125
118
|
# Options:
|
126
119
|
#
|
127
|
-
#
|
120
|
+
# params: A +Hash+ of params to pass to the Criteria API.
|
128
121
|
#
|
129
122
|
# Example:
|
130
123
|
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
# end
|
124
|
+
# <tt>Person.paginate(:conditions => { :field => "Test" }, :page => 1,
|
125
|
+
# :per_page => 20)</tt>
|
134
126
|
#
|
135
|
-
#
|
136
|
-
# belongs_to :person
|
137
|
-
# end
|
138
|
-
def has_many(association_name)
|
139
|
-
add_association(:has_many, association_name.to_s.classify, association_name)
|
140
|
-
end
|
141
|
-
|
142
|
-
# Create a one-to-many association between Documents.
|
143
|
-
def has_one(association_name)
|
144
|
-
add_association(:has_one, association_name.to_s.titleize, association_name)
|
145
|
-
end
|
146
|
-
|
147
|
-
# Adds timestamps on the Document in the form of the fields 'created_on'
|
148
|
-
# and 'last_modified'
|
149
|
-
def has_timestamps
|
150
|
-
field :created_at
|
151
|
-
field :last_modified
|
152
|
-
class_eval do
|
153
|
-
before_create \
|
154
|
-
:update_created_at,
|
155
|
-
:update_last_modified
|
156
|
-
before_save :update_last_modified
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
# Adds an index on the field specified. Options can be :unique => true or
|
161
|
-
# :unique => false. It will default to the latter.
|
162
|
-
def index(name, options = { :unique => false })
|
163
|
-
collection.create_index(name, options)
|
164
|
-
end
|
165
|
-
|
166
|
-
# Find all documents in paginated fashion given the supplied arguments.
|
167
|
-
# If no parameters are passed just default to offset 0 and limit 20.
|
127
|
+
# Returns paginated array of docs.
|
168
128
|
def paginate(params = {})
|
169
|
-
|
170
|
-
WillPaginate::Collection.create(
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
results = collection.find(selector, { :sort => params[:sort],
|
175
|
-
:limit => pager.per_page,
|
176
|
-
:skip => pager.offset })
|
177
|
-
pager.total_entries = results.count
|
178
|
-
pager.replace(results.collect { |doc| new(doc) })
|
129
|
+
criteria = Criteria.translate(:all, params)
|
130
|
+
WillPaginate::Collection.create(criteria.page, criteria.offset, 0) do |pager|
|
131
|
+
results = criteria.execute(self)
|
132
|
+
pager.total_entries = results.size
|
133
|
+
pager.replace(results)
|
179
134
|
end
|
180
135
|
end
|
181
136
|
|
@@ -193,7 +148,7 @@ module Mongoid #:nodoc:
|
|
193
148
|
#
|
194
149
|
# Returns: <tt>Criteria</tt>
|
195
150
|
def select(*args)
|
196
|
-
Criteria.new(:all).select(*args)
|
151
|
+
Criteria.new(:all, self).select(*args)
|
197
152
|
end
|
198
153
|
|
199
154
|
end
|
@@ -219,6 +174,12 @@ module Mongoid #:nodoc:
|
|
219
174
|
def initialize(attributes = {})
|
220
175
|
@attributes = attributes.symbolize_keys if attributes
|
221
176
|
@attributes = {} unless attributes
|
177
|
+
generate_key
|
178
|
+
end
|
179
|
+
|
180
|
+
# Return the +Document+ primary key.
|
181
|
+
def primary_key
|
182
|
+
self.class.primary_key
|
222
183
|
end
|
223
184
|
|
224
185
|
# Returns true is the Document has not been persisted to the database, false if it has.
|
@@ -226,27 +187,10 @@ module Mongoid #:nodoc:
|
|
226
187
|
@attributes[:_id].nil?
|
227
188
|
end
|
228
189
|
|
229
|
-
#
|
230
|
-
def
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
private
|
235
|
-
|
236
|
-
class << self
|
237
|
-
|
238
|
-
# Adds the association to the associations hash with the type as the key,
|
239
|
-
# then adds the accessors for the association.
|
240
|
-
def add_association(type, class_name, name)
|
241
|
-
define_method(name) do
|
242
|
-
Mongoid::Associations::Factory.create(type, name, self)
|
243
|
-
end
|
244
|
-
define_method("#{name}=") do |object|
|
245
|
-
object.parentize(self)
|
246
|
-
@attributes[name] = object.mongoidize
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
190
|
+
# Notify observers that this Document has changed.
|
191
|
+
def notify
|
192
|
+
changed(true)
|
193
|
+
notify_observers(self)
|
250
194
|
end
|
251
195
|
|
252
196
|
# Read from the attributes hash.
|
@@ -255,23 +199,37 @@ module Mongoid #:nodoc:
|
|
255
199
|
fields[symbol].value(@attributes[symbol])
|
256
200
|
end
|
257
201
|
|
258
|
-
#
|
259
|
-
|
260
|
-
|
261
|
-
self.created_at = Time.now
|
202
|
+
# Returns the id of the Document
|
203
|
+
def to_param
|
204
|
+
id.to_s
|
262
205
|
end
|
263
206
|
|
264
|
-
# Update the
|
265
|
-
|
266
|
-
|
267
|
-
|
207
|
+
# Update the document based on notify from child
|
208
|
+
def update(child)
|
209
|
+
@attributes.insert(child.association_name, child.attributes)
|
210
|
+
notify
|
268
211
|
end
|
269
212
|
|
270
213
|
# Write to the attributes hash.
|
271
214
|
def write_attribute(name, value)
|
272
215
|
symbol = name.to_sym
|
273
|
-
@attributes[name.to_sym] =
|
216
|
+
@attributes[name.to_sym] = value
|
217
|
+
notify
|
218
|
+
end
|
219
|
+
|
220
|
+
# Writes all the attributes of this Document, and delegate up to
|
221
|
+
# the parent.
|
222
|
+
def write_attributes(attrs)
|
223
|
+
@attributes = attrs
|
224
|
+
notify
|
274
225
|
end
|
275
226
|
|
227
|
+
private
|
228
|
+
def generate_key
|
229
|
+
if primary_key
|
230
|
+
values = primary_key.collect { |key| @attributes[key] }
|
231
|
+
@attributes[:_id] = values.join(" ").parameterize.to_s
|
232
|
+
end
|
233
|
+
end
|
276
234
|
end
|
277
235
|
end
|