mongoid-with-auth 1.9.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.
Files changed (104) hide show
  1. data/MIT_LICENSE +20 -0
  2. data/README.rdoc +49 -0
  3. data/lib/mongoid.rb +122 -0
  4. data/lib/mongoid/associations.rb +300 -0
  5. data/lib/mongoid/associations/belongs_to_related.rb +58 -0
  6. data/lib/mongoid/associations/embedded_in.rb +72 -0
  7. data/lib/mongoid/associations/embeds_many.rb +254 -0
  8. data/lib/mongoid/associations/embeds_one.rb +96 -0
  9. data/lib/mongoid/associations/has_many_related.rb +181 -0
  10. data/lib/mongoid/associations/has_one_related.rb +85 -0
  11. data/lib/mongoid/associations/meta_data.rb +29 -0
  12. data/lib/mongoid/associations/options.rb +57 -0
  13. data/lib/mongoid/associations/proxy.rb +24 -0
  14. data/lib/mongoid/attributes.rb +204 -0
  15. data/lib/mongoid/callbacks.rb +23 -0
  16. data/lib/mongoid/collection.rb +120 -0
  17. data/lib/mongoid/collections.rb +41 -0
  18. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  19. data/lib/mongoid/collections/master.rb +29 -0
  20. data/lib/mongoid/collections/operations.rb +41 -0
  21. data/lib/mongoid/collections/slaves.rb +45 -0
  22. data/lib/mongoid/components.rb +27 -0
  23. data/lib/mongoid/concern.rb +31 -0
  24. data/lib/mongoid/config.rb +205 -0
  25. data/lib/mongoid/contexts.rb +25 -0
  26. data/lib/mongoid/contexts/enumerable.rb +151 -0
  27. data/lib/mongoid/contexts/ids.rb +25 -0
  28. data/lib/mongoid/contexts/mongo.rb +285 -0
  29. data/lib/mongoid/contexts/paging.rb +50 -0
  30. data/lib/mongoid/criteria.rb +239 -0
  31. data/lib/mongoid/criterion/complex.rb +21 -0
  32. data/lib/mongoid/criterion/exclusion.rb +65 -0
  33. data/lib/mongoid/criterion/inclusion.rb +110 -0
  34. data/lib/mongoid/criterion/optional.rb +136 -0
  35. data/lib/mongoid/cursor.rb +81 -0
  36. data/lib/mongoid/deprecation.rb +22 -0
  37. data/lib/mongoid/dirty.rb +253 -0
  38. data/lib/mongoid/document.rb +311 -0
  39. data/lib/mongoid/errors.rb +108 -0
  40. data/lib/mongoid/extensions.rb +101 -0
  41. data/lib/mongoid/extensions/array/accessors.rb +17 -0
  42. data/lib/mongoid/extensions/array/aliasing.rb +4 -0
  43. data/lib/mongoid/extensions/array/assimilation.rb +26 -0
  44. data/lib/mongoid/extensions/array/conversions.rb +29 -0
  45. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  46. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  47. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  48. data/lib/mongoid/extensions/boolean/conversions.rb +22 -0
  49. data/lib/mongoid/extensions/date/conversions.rb +24 -0
  50. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  51. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  52. data/lib/mongoid/extensions/hash/accessors.rb +38 -0
  53. data/lib/mongoid/extensions/hash/assimilation.rb +39 -0
  54. data/lib/mongoid/extensions/hash/conversions.rb +45 -0
  55. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  56. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  57. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  58. data/lib/mongoid/extensions/nil/assimilation.rb +17 -0
  59. data/lib/mongoid/extensions/object/conversions.rb +33 -0
  60. data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
  61. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  62. data/lib/mongoid/extensions/string/conversions.rb +15 -0
  63. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  64. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  65. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  66. data/lib/mongoid/extras.rb +61 -0
  67. data/lib/mongoid/factory.rb +20 -0
  68. data/lib/mongoid/field.rb +59 -0
  69. data/lib/mongoid/fields.rb +65 -0
  70. data/lib/mongoid/finders.rb +136 -0
  71. data/lib/mongoid/identity.rb +39 -0
  72. data/lib/mongoid/indexes.rb +30 -0
  73. data/lib/mongoid/javascript.rb +21 -0
  74. data/lib/mongoid/javascript/functions.yml +37 -0
  75. data/lib/mongoid/matchers.rb +36 -0
  76. data/lib/mongoid/matchers/all.rb +11 -0
  77. data/lib/mongoid/matchers/default.rb +26 -0
  78. data/lib/mongoid/matchers/exists.rb +13 -0
  79. data/lib/mongoid/matchers/gt.rb +11 -0
  80. data/lib/mongoid/matchers/gte.rb +11 -0
  81. data/lib/mongoid/matchers/in.rb +11 -0
  82. data/lib/mongoid/matchers/lt.rb +11 -0
  83. data/lib/mongoid/matchers/lte.rb +11 -0
  84. data/lib/mongoid/matchers/ne.rb +11 -0
  85. data/lib/mongoid/matchers/nin.rb +11 -0
  86. data/lib/mongoid/matchers/size.rb +11 -0
  87. data/lib/mongoid/memoization.rb +33 -0
  88. data/lib/mongoid/named_scope.rb +37 -0
  89. data/lib/mongoid/observable.rb +30 -0
  90. data/lib/mongoid/paths.rb +62 -0
  91. data/lib/mongoid/persistence.rb +222 -0
  92. data/lib/mongoid/persistence/command.rb +39 -0
  93. data/lib/mongoid/persistence/insert.rb +50 -0
  94. data/lib/mongoid/persistence/insert_embedded.rb +38 -0
  95. data/lib/mongoid/persistence/remove.rb +39 -0
  96. data/lib/mongoid/persistence/remove_all.rb +37 -0
  97. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  98. data/lib/mongoid/persistence/update.rb +63 -0
  99. data/lib/mongoid/scope.rb +75 -0
  100. data/lib/mongoid/state.rb +39 -0
  101. data/lib/mongoid/timestamps.rb +27 -0
  102. data/lib/mongoid/version.rb +4 -0
  103. data/lib/mongoid/versioning.rb +27 -0
  104. metadata +284 -0
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Durran Jordan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,49 @@
1
+ = Overview
2
+
3
+ == About Mongoid
4
+
5
+ Mongoid is an ODM (Object-Document-Mapper) framework for MongoDB in Ruby.
6
+
7
+ == Project Tracking
8
+
9
+ * {Mongoid on Pivotal Tracker}[http://www.pivotaltracker.com/projects/27482]
10
+ * {Mongoid Google Group}[http://groups.google.com/group/mongoid]
11
+ * {Mongoid on CI Joe}[http://ci.mongoid.org/]
12
+ * {Mongoid Website and Documentation}[http://mongoid.org]
13
+
14
+ == Compatibility
15
+
16
+ Mongoid is developed against Ruby 1.8.6, 1.8.7, 1.9.1, 1.9.2
17
+
18
+ = Documentation
19
+
20
+ Please see the new Mongoid website for up-to-date documentation:
21
+ {mongoid.org}[http://mongoid.org]
22
+
23
+ = License
24
+
25
+ Copyright (c) 2009 Durran Jordan
26
+
27
+ Permission is hereby granted, free of charge, to any person obtaining
28
+ a copy of this software and associated documentation files (the
29
+ "Software"), to deal in the Software without restriction, including
30
+ without limitation the rights to use, copy, modify, merge, publish,
31
+ distribute, sublicense, and/or sell copies of the Software, and to
32
+ permit persons to whom the Software is furnished to do so, subject to
33
+ the following conditions:
34
+
35
+ The above copyright notice and this permission notice shall be
36
+ included in all copies or substantial portions of the Software.
37
+
38
+
39
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
40
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
41
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
42
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
43
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
44
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
45
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46
+
47
+ = Credits
48
+
49
+ Durran Jordan: durran at gmail dot com
@@ -0,0 +1,122 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) 2009 Durran Jordan
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ require "delegate"
23
+ require "singleton"
24
+ require "time"
25
+ require "validatable"
26
+ require "active_support/callbacks"
27
+ require "active_support/core_ext"
28
+ require "active_support/inflector"
29
+ require "active_support/time_with_zone"
30
+ require "will_paginate/collection"
31
+ require "mongo"
32
+ require "mongoid/concern"
33
+ require "mongoid/observable"
34
+ require "mongoid/associations"
35
+ require "mongoid/attributes"
36
+ require "mongoid/callbacks"
37
+ require "mongoid/collection"
38
+ require "mongoid/collections"
39
+ require "mongoid/config"
40
+ require "mongoid/contexts"
41
+ require "mongoid/criteria"
42
+ require "mongoid/cursor"
43
+ require "mongoid/deprecation"
44
+ require "mongoid/dirty"
45
+ require "mongoid/extensions"
46
+ require "mongoid/extras"
47
+ require "mongoid/errors"
48
+ require "mongoid/factory"
49
+ require "mongoid/field"
50
+ require "mongoid/fields"
51
+ require "mongoid/finders"
52
+ require "mongoid/identity"
53
+ require "mongoid/indexes"
54
+ require "mongoid/javascript"
55
+ require "mongoid/matchers"
56
+ require "mongoid/memoization"
57
+ require "mongoid/named_scope"
58
+ require "mongoid/paths"
59
+ require "mongoid/persistence"
60
+ require "mongoid/scope"
61
+ require "mongoid/state"
62
+ require "mongoid/timestamps"
63
+ require "mongoid/versioning"
64
+ require "mongoid/components"
65
+ require "mongoid/document"
66
+
67
+ module Mongoid #:nodoc
68
+
69
+ MONGODB_VERSION = "1.4.0"
70
+
71
+ class << self
72
+
73
+ # Sets the Mongoid configuration options. Best used by passing a block.
74
+ #
75
+ # Example:
76
+ #
77
+ # Mongoid.configure do |config|
78
+ # name = "mongoid_test"
79
+ # host = "localhost"
80
+ # config.allow_dynamic_fields = false
81
+ # config.master = Mongo::Connection.new.db(name)
82
+ # config.slaves = [
83
+ # Mongo::Connection.new(host, 27018, :slave_ok => true).db(name),
84
+ # Mongo::Connection.new(host, 27019, :slave_ok => true).db(name)
85
+ # ]
86
+ # end
87
+ #
88
+ # Returns:
89
+ #
90
+ # The Mongoid +Config+ singleton instance.
91
+ def configure
92
+ config = Mongoid::Config.instance
93
+ block_given? ? yield(config) : config
94
+ end
95
+
96
+ # Easy convenience method for having an alert generated from the
97
+ # deprecation module.
98
+ #
99
+ # Example:
100
+ #
101
+ # <tt>Mongoid.deprecate("Method no longer used")</tt>
102
+ def deprecate(message)
103
+ Mongoid::Deprecation.instance.alert(message)
104
+ end
105
+
106
+ alias :config :configure
107
+ end
108
+
109
+ # Take all the public instance methods from the Config singleton and allow
110
+ # them to be accessed through the Mongoid module directly.
111
+ #
112
+ # Example:
113
+ #
114
+ # <tt>Mongoid.database = Mongo::Connection.new.db("test")</tt>
115
+ Mongoid::Config.public_instance_methods(false).each do |name|
116
+ (class << self; self; end).class_eval <<-EOT
117
+ def #{name}(*args)
118
+ configure.send("#{name}", *args)
119
+ end
120
+ EOT
121
+ end
122
+ end
@@ -0,0 +1,300 @@
1
+ # encoding: utf-8
2
+ require "mongoid/associations/proxy"
3
+ require "mongoid/associations/belongs_to_related"
4
+ require "mongoid/associations/embedded_in"
5
+ require "mongoid/associations/embeds_many"
6
+ require "mongoid/associations/embeds_one"
7
+ require "mongoid/associations/has_many_related"
8
+ require "mongoid/associations/has_one_related"
9
+ require "mongoid/associations/options"
10
+ require "mongoid/associations/meta_data"
11
+
12
+ module Mongoid # :nodoc:
13
+ module Associations #:nodoc:
14
+ extend ActiveSupport::Concern
15
+ included do
16
+ cattr_accessor :embedded
17
+ self.embedded = false
18
+
19
+ class_inheritable_accessor :associations
20
+ self.associations = {}
21
+
22
+ delegate :embedded, :embedded?, :to => "self.class"
23
+ end
24
+
25
+ module InstanceMethods
26
+ # Returns the associations for the +Document+.
27
+ def associations
28
+ self.class.associations
29
+ end
30
+
31
+ # are we in an embeds_many?
32
+ def embedded_many?
33
+ embedded? and _parent.associations[association_name].association == EmbedsMany
34
+ end
35
+
36
+ # Update all the dirty child documents after an update.
37
+ def update_embedded(name)
38
+ association = send(name)
39
+ association.to_a.each { |doc| doc.save if doc.changed? || doc.new_record? } unless association.blank?
40
+ end
41
+
42
+ # Update the one-to-one relational association for the name.
43
+ def update_association(name)
44
+ association = send(name)
45
+ association.save if new_record? && !association.nil?
46
+ end
47
+
48
+ # Updates all the one-to-many relational associations for the name.
49
+ def update_associations(name)
50
+ send(name).each { |doc| doc.save } if new_record?
51
+ end
52
+ end
53
+
54
+ module ClassMethods
55
+ # Adds a relational association from the child Document to a Document in
56
+ # another database or collection.
57
+ #
58
+ # Options:
59
+ #
60
+ # name: A +Symbol+ that is the related class name.
61
+ #
62
+ # Example:
63
+ #
64
+ # class Game
65
+ # include Mongoid::Document
66
+ # belongs_to_related :person
67
+ # end
68
+ #
69
+ def belongs_to_related(name, options = {}, &block)
70
+ opts = optionize(name, options, fk(name, options), &block)
71
+ associate(Associations::BelongsToRelated, opts)
72
+ field(opts.foreign_key, :type => Mongoid.use_object_ids ? BSON::ObjectId : String)
73
+ index(opts.foreign_key) unless embedded?
74
+ end
75
+
76
+ # Gets whether or not the document is embedded.
77
+ #
78
+ # Example:
79
+ #
80
+ # <tt>Person.embedded?</tt>
81
+ #
82
+ # Returns:
83
+ #
84
+ # <tt>true</tt> if embedded, <tt>false</tt> if not.
85
+ def embedded?
86
+ !!self.embedded
87
+ end
88
+
89
+ # Adds the association back to the parent document. This macro is
90
+ # necessary to set the references from the child back to the parent
91
+ # document. If a child does not define this association calling
92
+ # persistence methods on the child object will cause a save to fail.
93
+ #
94
+ # Options:
95
+ #
96
+ # name: A +Symbol+ that matches the name of the parent class.
97
+ #
98
+ # Example:
99
+ #
100
+ # class Person
101
+ # include Mongoid::Document
102
+ # embeds_many :addresses
103
+ # end
104
+ #
105
+ # class Address
106
+ # include Mongoid::Document
107
+ # embedded_in :person, :inverse_of => :addresses
108
+ # end
109
+ def embedded_in(name, options = {}, &block)
110
+ unless options.has_key?(:inverse_of)
111
+ raise Errors::InvalidOptions.new("Options for embedded_in association must include :inverse_of")
112
+ end
113
+ self.embedded = true
114
+ associate(Associations::EmbeddedIn, optionize(name, options, nil, &block))
115
+ end
116
+
117
+ alias :belongs_to :embedded_in
118
+
119
+ # Adds the association from a parent document to its children. The name
120
+ # of the association needs to be a pluralized form of the child class
121
+ # name.
122
+ #
123
+ # Options:
124
+ #
125
+ # name: A +Symbol+ that is the plural child class name.
126
+ #
127
+ # Example:
128
+ #
129
+ # class Person
130
+ # include Mongoid::Document
131
+ # embeds_many :addresses
132
+ # end
133
+ #
134
+ # class Address
135
+ # include Mongoid::Document
136
+ # embedded_in :person, :inverse_of => :addresses
137
+ # end
138
+ def embeds_many(name, options = {}, &block)
139
+ associate(Associations::EmbedsMany, optionize(name, options, nil, &block))
140
+ unless name == :versions
141
+ after_update do |document|
142
+ document.update_embedded(name)
143
+ end
144
+ end
145
+ end
146
+
147
+ alias :embed_many :embeds_many
148
+ alias :has_many :embeds_many
149
+
150
+ # Adds the association from a parent document to its child. The name
151
+ # of the association needs to be a singular form of the child class
152
+ # name.
153
+ #
154
+ # Options:
155
+ #
156
+ # name: A +Symbol+ that is the plural child class name.
157
+ #
158
+ # Example:
159
+ #
160
+ # class Person
161
+ # include Mongoid::Document
162
+ # embeds_one :name
163
+ # end
164
+ #
165
+ # class Name
166
+ # include Mongoid::Document
167
+ # embedded_in :person
168
+ # end
169
+ def embeds_one(name, options = {}, &block)
170
+ opts = optionize(name, options, nil, &block)
171
+ type = Associations::EmbedsOne
172
+ associate(type, opts)
173
+ add_builder(type, opts)
174
+ add_creator(type, opts)
175
+ after_update do |document|
176
+ document.update_embedded(name)
177
+ end
178
+ end
179
+
180
+ alias :embed_one :embeds_one
181
+ alias :has_one :embeds_one
182
+
183
+ # Adds a relational association from the Document to many Documents in
184
+ # another database or collection.
185
+ #
186
+ # Options:
187
+ #
188
+ # name: A +Symbol+ that is the related class name pluralized.
189
+ #
190
+ # Example:
191
+ #
192
+ # class Person
193
+ # include Mongoid::Document
194
+ # has_many_related :posts
195
+ # end
196
+ #
197
+ def has_many_related(name, options = {}, &block)
198
+ associate(Associations::HasManyRelated, optionize(name, options, fk(self.name, options), &block))
199
+ before_save do |document|
200
+ document.update_associations(name)
201
+ end
202
+ end
203
+
204
+ # Adds a relational association from the Document to one Document in
205
+ # another database or collection.
206
+ #
207
+ # Options:
208
+ #
209
+ # name: A +Symbol+ that is the related class name pluralized.
210
+ #
211
+ # Example:
212
+ #
213
+ # class Person
214
+ # include Mongoid::Document
215
+ # has_one_related :game
216
+ # end
217
+ def has_one_related(name, options = {}, &block)
218
+ associate(Associations::HasOneRelated, optionize(name, options, fk(self.name, options), &block))
219
+ before_save do |document|
220
+ document.update_association(name)
221
+ end
222
+ end
223
+
224
+ # Returns the macro associated with the supplied association name. This
225
+ # will return has_one, has_many, belongs_to or nil.
226
+ #
227
+ # Options:
228
+ #
229
+ # name: The association name.
230
+ #
231
+ # Example:
232
+ #
233
+ # <tt>Person.reflect_on_association(:addresses)</tt>
234
+ def reflect_on_association(name)
235
+ association = associations[name.to_s]
236
+ association ? association.macro : nil
237
+ end
238
+
239
+ protected
240
+ # Adds the association to the associations hash with the type as the key,
241
+ # then adds the accessors for the association. The defined setters and
242
+ # getters for the associations will perform the necessary memoization.
243
+ #
244
+ # Example:
245
+ #
246
+ # <tt>Person.associate(EmbedsMany, { :name => :addresses })</tt>
247
+ def associate(type, options)
248
+ name = options.name.to_s
249
+ associations[name] = MetaData.new(type, options)
250
+ define_method(name) { memoized(name) { type.instantiate(self, options) } }
251
+ define_method("#{name}=") do |object|
252
+ unmemoize(name)
253
+ memoized(name) { type.update(object, self, options) }
254
+ end
255
+ end
256
+
257
+ # Adds a builder for a has_one association. This comes in the form of
258
+ # build_name(attributes)
259
+ def add_builder(type, options)
260
+ name = options.name.to_s
261
+ define_method("build_#{name}") do |attrs|
262
+ reset(name) { type.new(self, (attrs || {}).stringify_keys, options) }
263
+ end
264
+ end
265
+
266
+ # Adds a creator for a has_one association. This comes in the form of
267
+ # create_name(attributes)
268
+ def add_creator(type, options)
269
+ name = options.name.to_s
270
+ define_method("create_#{name}") do |attrs|
271
+ document = send("build_#{name}", attrs)
272
+ document.save; document
273
+ end
274
+ end
275
+
276
+ # build the options given the params.
277
+ def optionize(name, options, foreign_key, &block)
278
+ Associations::Options.new(
279
+ options.merge(:name => name, :foreign_key => foreign_key, :extend => block)
280
+ )
281
+ end
282
+
283
+ # Find the foreign key.
284
+ def fk(name, options)
285
+ options[:foreign_key] || name.to_s.foreign_key
286
+ end
287
+
288
+ # Build the association options.
289
+ def build_options(name, options, &block)
290
+ Associations::Options.new(
291
+ options.merge(
292
+ :name => name,
293
+ :foreign_key => foreign_key(name, options),
294
+ :extend => block
295
+ )
296
+ )
297
+ end
298
+ end
299
+ end
300
+ end