mongoid 0.11.9 → 0.12.0

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/HISTORY CHANGED
@@ -1,3 +1,43 @@
1
+ === 0.12.0
2
+ - Has one now works as expected:
3
+
4
+ - Has one associations will return nil, instead
5
+ of the proxy if the association has not been
6
+ set.
7
+
8
+ - Building/creating a has one is no longer handled
9
+ by calling the Document#association#build() or create(),
10
+ this is now handled by Document#build_name and
11
+ Document#create_name where "name" is the name
12
+ of the has one association.
13
+
14
+ - Passing a _type attribute to the #build_name
15
+ and #create_name methods will build/create
16
+ objects of that type, useful for creating
17
+ specific subclasses.
18
+
19
+ - The existing #build and #create methods will be
20
+ removed in the next release.
21
+
22
+ - Removed all dynamic finders. If you need to have
23
+ functionality similar to "find_or_(create|initialize)_by"
24
+ you can use the 2 new finders:
25
+
26
+ - Document.find_or_create_by(attributes): Will
27
+ look for a document in the database with the
28
+ supplied attributes, if found it will return the
29
+ document otherwise will create a new one with
30
+ the supplied attributes.
31
+
32
+ - Document.find_or_initialize_by(attributes): Will
33
+ look for a document in the database with the
34
+ supplied attributes, if found it will return the
35
+ document otherwise will instantiate a new one with
36
+ the supplied attributes.
37
+
38
+ - Fixed issue with empty hashes and arrays not getting
39
+ set on document instantiation.
40
+
1
41
  === 0.11.9
2
42
  - Fixed issue with non-us time zones and formats
3
43
  parsing incorrectly.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.9
1
+ 0.12.0
@@ -44,7 +44,6 @@ require "mongoid/commands"
44
44
  require "mongoid/config"
45
45
  require "mongoid/complex_criterion"
46
46
  require "mongoid/criteria"
47
- require "mongoid/dynamic_finder"
48
47
  require "mongoid/extensions"
49
48
  require "mongoid/errors"
50
49
  require "mongoid/field"
@@ -154,10 +154,11 @@ module Mongoid # :nodoc:
154
154
  # belongs_to :person
155
155
  # end
156
156
  def has_one(name, options = {})
157
- add_association(
158
- Associations::HasOne,
159
- Associations::Options.new(options.merge(:name => name))
160
- )
157
+ opts = Associations::Options.new(options.merge(:name => name))
158
+ type = Associations::HasOne
159
+ add_association(type, opts)
160
+ add_builder(type, opts)
161
+ add_creator(type, opts)
161
162
  end
162
163
 
163
164
  # Adds a relational association from the Document to one Document in
@@ -211,6 +212,25 @@ module Mongoid # :nodoc:
211
212
  reset(name) { type.update(object, self, options) }
212
213
  end
213
214
  end
215
+
216
+ # Adds a builder for a has_one association. This comes in the form of
217
+ # build_name(attributes)
218
+ def add_builder(type, options)
219
+ name = options.name
220
+ define_method("build_#{name}") do |attrs|
221
+ reset(name) { type.new(self, attrs, options) }
222
+ end
223
+ end
224
+
225
+ # Adds a creator for a has_one association. This comes in the form of
226
+ # create_name(attributes)
227
+ def add_creator(type, options)
228
+ name = options.name
229
+ define_method("create_#{name}") do |attrs|
230
+ document = send("build_#{name}", attrs)
231
+ document.save; document
232
+ end
233
+ end
214
234
  end
215
235
  end
216
236
  end
@@ -33,17 +33,13 @@ module Mongoid #:nodoc:
33
33
  # options: The association options.
34
34
  def initialize(document, attributes, options)
35
35
  @parent, @options, @association_name = document, options, options.name
36
- unless attributes.nil?
37
- klass = attributes[:_type] ? attributes[:_type].constantize : nil
38
- @document = attributes.assimilate(@parent, @options, klass)
39
- else
40
- @document = nil
41
- end
36
+ klass = attributes[:_type] ? attributes[:_type].constantize : nil
37
+ @document = attributes.assimilate(@parent, @options, klass)
42
38
  end
43
39
 
44
40
  # Delegate all missing methods over to the +Document+.
45
41
  def method_missing(name, *args, &block)
46
- @document.send(name, *args, &block) unless @document.nil?
42
+ @document.send(name, *args, &block)
47
43
  end
48
44
 
49
45
  # Used for setting the association via a nested attributes setter on the
@@ -52,11 +48,6 @@ module Mongoid #:nodoc:
52
48
  build(attributes)
53
49
  end
54
50
 
55
- # This should delegate to the document.
56
- def nil?
57
- @document.nil?
58
- end
59
-
60
51
  # This will get deprecated
61
52
  def to_a
62
53
  [@document]
@@ -64,7 +55,7 @@ module Mongoid #:nodoc:
64
55
 
65
56
  # Need to override here for when the underlying document is nil.
66
57
  def valid?
67
- @document ? @document.valid? : false
58
+ @document.valid?
68
59
  end
69
60
 
70
61
  class << self
@@ -77,6 +68,7 @@ module Mongoid #:nodoc:
77
68
  # options: The association options.
78
69
  def instantiate(document, options)
79
70
  attributes = document.attributes[options.name]
71
+ return nil if attributes.blank?
80
72
  new(document, attributes, options)
81
73
  end
82
74
 
@@ -98,11 +90,7 @@ module Mongoid #:nodoc:
98
90
  #
99
91
  # <tt>HasOne.update({:first_name => "Hank"}, person, options)</tt>
100
92
  def update(child, parent, options)
101
- if child.nil?
102
- return parent.attributes[options.name] = nil
103
- else
104
- return child.assimilate(parent, options)
105
- end
93
+ child.assimilate(parent, options)
106
94
  end
107
95
  end
108
96
 
@@ -17,7 +17,7 @@ module Mongoid #:nodoc:
17
17
  if Mongoid.allow_dynamic_fields && !respond_to?("#{key}=")
18
18
  @attributes[key] = value
19
19
  else
20
- send("#{key}=", value) unless value.blank?
20
+ send("#{key}=", value) unless (value.is_a?(String) && value.blank?)
21
21
  end
22
22
  end
23
23
  end
@@ -123,8 +123,12 @@ module Mongoid #:nodoc:
123
123
  define_method("#{name}_attributes=") do |attrs|
124
124
  reject(attrs, options)
125
125
  association = send(name)
126
- update(association, true)
127
- association.nested_build(attrs)
126
+ if association
127
+ update(association, true)
128
+ association.nested_build(attrs)
129
+ else
130
+ send("build_#{name}", attrs)
131
+ end
128
132
  end
129
133
  end
130
134
  end
@@ -12,6 +12,7 @@ require "mongoid/extensions/hash/assimilation"
12
12
  require "mongoid/extensions/hash/conversions"
13
13
  require "mongoid/extensions/hash/criteria_helpers"
14
14
  require "mongoid/extensions/integer/conversions"
15
+ require "mongoid/extensions/nil/assimilation"
15
16
  require "mongoid/extensions/object/conversions"
16
17
  require "mongoid/extensions/string/conversions"
17
18
  require "mongoid/extensions/string/inflections"
@@ -52,6 +53,10 @@ class Integer #:nodoc
52
53
  extend Mongoid::Extensions::Integer::Conversions
53
54
  end
54
55
 
56
+ class NilClass #:nodoc
57
+ include Mongoid::Extensions::Nil::Assimilation
58
+ end
59
+
55
60
  class Object #:nodoc:
56
61
  include Mongoid::Extensions::Object::Conversions
57
62
  end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Extensions #:nodoc:
4
+ module Nil #:nodoc:
5
+ module Assimilation #:nodoc:
6
+ # Will remove the child object from the parent.
7
+ def assimilate(parent, options, type = nil)
8
+ parent.remove_attribute(options.name); self
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -54,6 +54,30 @@ module Mongoid #:nodoc:
54
54
  end
55
55
  end
56
56
 
57
+ # Find the first +Document+ given the conditions, or creates a new document
58
+ # with the conditions that were supplied
59
+ #
60
+ # Options:
61
+ #
62
+ # args: A +Hash+ of attributes
63
+ #
64
+ # <tt>Person.find_or_create_by(:attribute => "value")</tt>
65
+ def find_or_create_by(attrs = {})
66
+ first(:conditions => attrs) || self.create(attrs)
67
+ end
68
+
69
+ # Find the first +Document+ given the conditions, or instantiates a new document
70
+ # with the conditions that were supplied
71
+ #
72
+ # Options:
73
+ #
74
+ # args: A +Hash+ of attributes
75
+ #
76
+ # <tt>Person.find_or_initialize_by(:attribute => "value")</tt>
77
+ def find_or_initialize_by(attrs = {})
78
+ first(:conditions => attrs) || self.new(attrs)
79
+ end
80
+
57
81
  # Find the first +Document+ given the conditions.
58
82
  #
59
83
  # Options:
@@ -102,12 +126,12 @@ module Mongoid #:nodoc:
102
126
  # Example:
103
127
  #
104
128
  # <tt>Person.find_all_by_title_and_age("Sir", 30)</tt>
105
- def method_missing(name, *args)
106
- dyna = DynamicFinder.new(name, *args)
107
- finder, conditions = dyna.finder, dyna.conditions
108
- results = find(finder, :conditions => conditions)
109
- results ? results : dyna.create(self)
110
- end
129
+ # def method_missing(name, *args)
130
+ # dyna = DynamicFinder.new(name, *args)
131
+ # finder, conditions = dyna.finder, dyna.conditions
132
+ # results = find(finder, :conditions => conditions)
133
+ # results ? results : dyna.create(self)
134
+ # end
111
135
 
112
136
  # Convenience method for returning the min value of a field.
113
137
  #
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongoid}
8
- s.version = "0.11.9"
8
+ s.version = "0.12.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Durran Jordan"]
12
- s.date = %q{2010-01-07}
12
+ s.date = %q{2010-01-08}
13
13
  s.email = %q{durran@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "README.textile"
@@ -45,7 +45,6 @@ Gem::Specification.new do |s|
45
45
  "lib/mongoid/config.rb",
46
46
  "lib/mongoid/criteria.rb",
47
47
  "lib/mongoid/document.rb",
48
- "lib/mongoid/dynamic_finder.rb",
49
48
  "lib/mongoid/errors.rb",
50
49
  "lib/mongoid/extensions.rb",
51
50
  "lib/mongoid/extensions/array/accessors.rb",
@@ -61,6 +60,7 @@ Gem::Specification.new do |s|
61
60
  "lib/mongoid/extensions/hash/conversions.rb",
62
61
  "lib/mongoid/extensions/hash/criteria_helpers.rb",
63
62
  "lib/mongoid/extensions/integer/conversions.rb",
63
+ "lib/mongoid/extensions/nil/assimilation.rb",
64
64
  "lib/mongoid/extensions/object/conversions.rb",
65
65
  "lib/mongoid/extensions/string/conversions.rb",
66
66
  "lib/mongoid/extensions/string/inflections.rb",
@@ -100,7 +100,6 @@ Gem::Specification.new do |s|
100
100
  "spec/unit/mongoid/config_spec.rb",
101
101
  "spec/unit/mongoid/criteria_spec.rb",
102
102
  "spec/unit/mongoid/document_spec.rb",
103
- "spec/unit/mongoid/dynamic_finder_spec.rb",
104
103
  "spec/unit/mongoid/errors_spec.rb",
105
104
  "spec/unit/mongoid/extensions/array/accessors_spec.rb",
106
105
  "spec/unit/mongoid/extensions/array/assimilation_spec.rb",
@@ -115,6 +114,7 @@ Gem::Specification.new do |s|
115
114
  "spec/unit/mongoid/extensions/hash/conversions_spec.rb",
116
115
  "spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb",
117
116
  "spec/unit/mongoid/extensions/integer/conversions_spec.rb",
117
+ "spec/unit/mongoid/extensions/nil/assimilation_spec.rb",
118
118
  "spec/unit/mongoid/extensions/object/conversions_spec.rb",
119
119
  "spec/unit/mongoid/extensions/string/conversions_spec.rb",
120
120
  "spec/unit/mongoid/extensions/string/inflections_spec.rb",
@@ -159,7 +159,6 @@ Gem::Specification.new do |s|
159
159
  "spec/unit/mongoid/config_spec.rb",
160
160
  "spec/unit/mongoid/criteria_spec.rb",
161
161
  "spec/unit/mongoid/document_spec.rb",
162
- "spec/unit/mongoid/dynamic_finder_spec.rb",
163
162
  "spec/unit/mongoid/errors_spec.rb",
164
163
  "spec/unit/mongoid/extensions/array/accessors_spec.rb",
165
164
  "spec/unit/mongoid/extensions/array/assimilation_spec.rb",
@@ -174,6 +173,7 @@ Gem::Specification.new do |s|
174
173
  "spec/unit/mongoid/extensions/hash/conversions_spec.rb",
175
174
  "spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb",
176
175
  "spec/unit/mongoid/extensions/integer/conversions_spec.rb",
176
+ "spec/unit/mongoid/extensions/nil/assimilation_spec.rb",
177
177
  "spec/unit/mongoid/extensions/object/conversions_spec.rb",
178
178
  "spec/unit/mongoid/extensions/string/conversions_spec.rb",
179
179
  "spec/unit/mongoid/extensions/string/inflections_spec.rb",
@@ -72,7 +72,7 @@ describe Mongoid::Associations do
72
72
 
73
73
  before do
74
74
  @address = @person.addresses.create(:street => "Oxford St")
75
- @name = @person.name.create(:first_name => "Gordon")
75
+ @name = @person.create_name(:first_name => "Gordon")
76
76
  end
77
77
 
78
78
  it "persists all the associations properly" do
@@ -91,7 +91,7 @@ describe Mongoid::Associations do
91
91
  it "persists all the associations properly" do
92
92
  from_db = Person.find(@person.id)
93
93
  phone = from_db.phone_numbers.first
94
- phone.country_code.create(:code => 1)
94
+ phone.create_country_code(:code => 1)
95
95
  from_db.phone_numbers.first.country_code.code.should == 1
96
96
  end
97
97
 
@@ -106,58 +106,72 @@ describe Mongoid::Document do
106
106
  before do
107
107
  @person = Person.create(:title => "Lead")
108
108
  @person.addresses.create(:street => "1st Street")
109
- @person.name.create(:first_name => "Emmanuel")
109
+ @person.create_name(:first_name => "Emmanuel")
110
110
  @person.save
111
111
  end
112
112
 
113
113
  it "deletes the document" do
114
114
  @person.addresses.first.destroy
115
+ @person.name.should_not be_nil
115
116
  @person.name.destroy
116
117
  @person.addresses.first.should be_nil
117
- @person.name.document.should be_nil
118
+ @person.name.should be_nil
118
119
  end
119
120
 
120
121
  end
121
122
 
122
123
  end
123
124
 
124
- context "using dynamic finders" do
125
+ context ".find_or_create_by" do
125
126
 
126
127
  before do
127
- @person = Person.create(:title => "Mr", :age => 25)
128
+ @person = Person.create(:title => "Senior")
128
129
  end
129
130
 
130
- context "finding by a single attribute" do
131
+ context "when the document is found" do
131
132
 
132
- it "returns found documents" do
133
- Person.find_by_title("Mr").should == @person
133
+ it "returns the document" do
134
+ Person.find_or_create_by(:title => "Senior").should == @person
134
135
  end
135
136
 
136
137
  end
137
138
 
138
- context "finding by multiple attributes" do
139
+ context "when the document is not found" do
139
140
 
140
- it "returns found documents" do
141
- Person.find_by_title_and_age("Mr", 25).should == @person
141
+ it "creates a new document" do
142
+ person = Person.find_or_create_by(:title => "Senorita")
143
+ person.title.should == "Senorita"
144
+ person.should_not be_a_new_record
142
145
  end
143
146
 
144
147
  end
145
148
 
146
- context "finding all by a single attribute" do
149
+ end
150
+
151
+ context ".find_or_initialize_by" do
152
+
153
+ before do
154
+ @person = Person.create(:title => "Senior")
155
+ end
156
+
157
+ context "when the document is found" do
147
158
 
148
- it "returns found documents" do
149
- Person.find_all_by_title("Mr").should == [@person]
159
+ it "returns the document" do
160
+ Person.find_or_initialize_by(:title => "Senior").should == @person
150
161
  end
151
162
 
152
163
  end
153
164
 
154
- context "finding all by multiple attributes" do
165
+ context "when the document is not found" do
155
166
 
156
- it "returns found documents" do
157
- Person.find_all_by_title_and_age("Mr", 25).should == [@person]
167
+ it "returns a new document" do
168
+ person = Person.find_or_initialize_by(:title => "Senorita")
169
+ person.title.should == "Senorita"
170
+ person.should be_a_new_record
158
171
  end
159
172
 
160
173
  end
174
+
161
175
  end
162
176
 
163
177
  describe "#find" do
@@ -204,18 +218,6 @@ describe Mongoid::Document do
204
218
 
205
219
  end
206
220
 
207
- describe "#find_by_id" do
208
-
209
- before do
210
- @person = Person.create
211
- end
212
-
213
- it "returns the document with the matching id" do
214
- Person.find_by_id(@person.id).should == @person
215
- end
216
-
217
- end
218
-
219
221
  describe "#group" do
220
222
 
221
223
  before do
@@ -35,6 +35,7 @@ class Person
35
35
  field :employer_id
36
36
  field :lunch_time, :type => Time
37
37
  field :aliases, :type => Array
38
+ field :map, :type => Hash
38
39
  field :score, :type => Integer
39
40
 
40
41
  attr_reader :rescored
@@ -91,15 +91,52 @@ describe Mongoid::Associations::HasOne do
91
91
 
92
92
  end
93
93
 
94
- describe "#initialize" do
94
+ describe ".instantiate" do
95
+
96
+ context "when the attributes are nil" do
97
+
98
+ before do
99
+ @document = Person.new
100
+ @association = Mongoid::Associations::HasOne.instantiate(
101
+ @document,
102
+ Mongoid::Associations::Options.new(:name => :name)
103
+ )
104
+ end
105
+
106
+ it "returns nil" do
107
+ @association.should be_nil
108
+ end
109
+
110
+ end
111
+
112
+ context "when attributes are empty" do
113
+
114
+ before do
115
+ @document = stub(:attributes => { :name => {} })
116
+ @association = Mongoid::Associations::HasOne.instantiate(
117
+ @document,
118
+ Mongoid::Associations::Options.new(:name => :name)
119
+ )
120
+ end
121
+
122
+ it "returns nil" do
123
+ @association.should be_nil
124
+ end
95
125
 
96
- before do
97
- @document = stub(:attributes => { :writer => { :speed => 500, :_type => "HtmlWriter" } }, :update => true)
98
- @options = Mongoid::Associations::Options.new(:name => :writer)
99
126
  end
100
127
 
101
- it "delegates to new" do
102
- Mongoid::Associations::HasOne.new(@document, @document.attributes[:writer], @options)
128
+ context "when attributes exist" do
129
+
130
+ before do
131
+ @document = stub(:attributes => { :name => { :first_name => "Test" } })
132
+ @options = Mongoid::Associations::Options.new(:name => :name)
133
+ end
134
+
135
+ it "delegates to new" do
136
+ Mongoid::Associations::HasOne.expects(:new).with(@document, { :first_name => "Test" }, @options)
137
+ Mongoid::Associations::HasOne.instantiate(@document, @options)
138
+ end
139
+
103
140
  end
104
141
 
105
142
  end
@@ -131,34 +168,6 @@ describe Mongoid::Associations::HasOne do
131
168
 
132
169
  end
133
170
 
134
- context "when the document is nil" do
135
-
136
- before do
137
- @association = Mongoid::Associations::HasOne.new(
138
- @document,
139
- {},
140
- Mongoid::Associations::Options.new(:name => :mixed_drink)
141
- )
142
- end
143
-
144
- describe "#new_record?" do
145
-
146
- it "returns true" do
147
- @association.should be_new_record
148
- end
149
-
150
- end
151
-
152
- context "attribute getters" do
153
-
154
- it "returns nil" do
155
- @association.name.should be_nil
156
- end
157
-
158
- end
159
-
160
- end
161
-
162
171
  end
163
172
 
164
173
  describe "#nested_build" do
@@ -182,24 +191,6 @@ describe Mongoid::Associations::HasOne do
182
191
 
183
192
  end
184
193
 
185
- describe ".instantiate" do
186
-
187
- context "when attributes exist" do
188
-
189
- before do
190
- @document = stub(:attributes => { :name => { :first_name => "Test" } })
191
- @options = Mongoid::Associations::Options.new(:name => :name)
192
- end
193
-
194
- it "delegates to new" do
195
- Mongoid::Associations::HasOne.expects(:new).with(@document, { :first_name => "Test" }, @options)
196
- Mongoid::Associations::HasOne.instantiate(@document, @options)
197
- end
198
-
199
- end
200
-
201
- end
202
-
203
194
  describe ".macro" do
204
195
 
205
196
  it "returns :has_one" do
@@ -255,20 +246,6 @@ describe Mongoid::Associations::HasOne do
255
246
 
256
247
  describe "#valid?" do
257
248
 
258
- context "when the document is nil" do
259
-
260
- before do
261
- @document = stub(:attributes => {})
262
- @options = Mongoid::Associations::Options.new(:name => :name)
263
- @association = Mongoid::Associations::HasOne.instantiate(@document, @options)
264
- end
265
-
266
- it "returns false" do
267
- @association.valid?.should be_false
268
- end
269
-
270
- end
271
-
272
249
  context "when the document is not nil" do
273
250
 
274
251
  before do
@@ -139,6 +139,104 @@ describe Mongoid::Associations do
139
139
 
140
140
  end
141
141
 
142
+ describe "#build_*" do
143
+
144
+ before do
145
+ @canvas = Canvas.new
146
+ end
147
+
148
+ context "when type is passed in" do
149
+
150
+ before do
151
+ @writer = @canvas.build_writer(:speed => 250, :_type => "HtmlWriter")
152
+ end
153
+
154
+ it "returns a new document" do
155
+ @writer.should_not be_nil
156
+ end
157
+
158
+ it "returns the properly typed document" do
159
+ @writer.should be_a_kind_of(HtmlWriter)
160
+ end
161
+
162
+ it "sets the appropriate attributes" do
163
+ @writer.speed.should == 250
164
+ end
165
+
166
+ end
167
+
168
+ context "when type is not passed in" do
169
+
170
+ before do
171
+ @writer = @canvas.build_writer(:speed => 250)
172
+ end
173
+
174
+ it "returns a new document" do
175
+ @writer.should_not be_nil
176
+ end
177
+
178
+ it "returns the properly typed document" do
179
+ @writer.should be_a_kind_of(Writer)
180
+ end
181
+
182
+ it "sets the appropriate attributes" do
183
+ @writer.speed.should == 250
184
+ end
185
+
186
+ end
187
+
188
+ end
189
+
190
+ describe "#create_*" do
191
+
192
+ before do
193
+ @canvas = Canvas.new
194
+ end
195
+
196
+ context "when type is passed in" do
197
+
198
+ before do
199
+ Mongoid::Commands::Save.expects(:execute)
200
+ @writer = @canvas.create_writer(:speed => 250, :_type => "HtmlWriter")
201
+ end
202
+
203
+ it "returns a new document" do
204
+ @writer.should_not be_nil
205
+ end
206
+
207
+ it "returns the properly typed document" do
208
+ @writer.should be_a_kind_of(HtmlWriter)
209
+ end
210
+
211
+ it "sets the appropriate attributes" do
212
+ @writer.speed.should == 250
213
+ end
214
+
215
+ end
216
+
217
+ context "when type is not passed in" do
218
+
219
+ before do
220
+ Mongoid::Commands::Save.expects(:execute)
221
+ @writer = @canvas.create_writer(:speed => 250, :_type => "HtmlWriter")
222
+ end
223
+
224
+ it "returns a new document" do
225
+ @writer.should_not be_nil
226
+ end
227
+
228
+ it "returns the properly typed document" do
229
+ @writer.should be_a_kind_of(Writer)
230
+ end
231
+
232
+ it "sets the appropriate attributes" do
233
+ @writer.speed.should == 250
234
+ end
235
+
236
+ end
237
+
238
+ end
239
+
142
240
  describe ".has_many" do
143
241
 
144
242
  it "adds a new Association to the collection" do
@@ -208,19 +306,28 @@ describe Mongoid::Associations do
208
306
 
209
307
  describe ".has_one" do
210
308
 
309
+ before do
310
+ @person = Person.new
311
+ end
312
+
211
313
  it "adds a new Association to the document" do
212
- person = Person.new
213
- person.name.first_name.should be_nil
314
+ @person.name.should be_nil
214
315
  end
215
316
 
216
317
  it "creates a reader for the association" do
217
- person = Person.new
218
- person.should respond_to(:name)
318
+ @person.should respond_to(:name)
219
319
  end
220
320
 
221
321
  it "creates a writer for the association" do
222
- person = Person.new
223
- person.should respond_to(:name=)
322
+ @person.should respond_to(:name=)
323
+ end
324
+
325
+ it "creates a builder for the association" do
326
+ @person.should respond_to(:build_name)
327
+ end
328
+
329
+ it "creates a creator for the association" do
330
+ @person.should respond_to(:create_name)
224
331
  end
225
332
 
226
333
  context "when setting the association directly" do
@@ -233,6 +233,36 @@ describe Mongoid::Attributes do
233
233
 
234
234
  end
235
235
 
236
+ context "when an empty array is provided in the attributes" do
237
+
238
+ before do
239
+ @attributes = {
240
+ :aliases => []
241
+ }
242
+ @person = Person.new(@attributes)
243
+ end
244
+
245
+ it "sets the empty array" do
246
+ @person.aliases.should == []
247
+ end
248
+
249
+ end
250
+
251
+ context "when an empty hash is provided in the attributes" do
252
+
253
+ before do
254
+ @attributes = {
255
+ :map => {}
256
+ }
257
+ @person = Person.new(@attributes)
258
+ end
259
+
260
+ it "sets the empty hash" do
261
+ @person.map.should == {}
262
+ end
263
+
264
+ end
265
+
236
266
  end
237
267
 
238
268
  context "updating when attributes already exist" do
@@ -660,7 +660,7 @@ describe Mongoid::Document do
660
660
 
661
661
  it "removes the child document attributes" do
662
662
  @person.remove(@name)
663
- @person.name.document.should be_nil
663
+ @person.name.should be_nil
664
664
  end
665
665
 
666
666
  end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Extensions::Nil::Assimilation do
4
+
5
+ describe "#assimilate" do
6
+
7
+ before do
8
+ @name = Name.new(:first_name => "Durran")
9
+ @parent = Person.new(:title => "Mr.", :name => @name)
10
+ @options = Mongoid::Associations::Options.new(:name => :name)
11
+ end
12
+
13
+ it "removes the child attribute from the parent" do
14
+ nil.assimilate(@parent, @options)
15
+ @parent.attributes[:name].should be_nil
16
+ end
17
+
18
+ it "returns nil" do
19
+ nil.assimilate(@parent, @options).should be_nil
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -140,16 +140,74 @@ describe Mongoid::Finders do
140
140
 
141
141
  end
142
142
 
143
- describe ".find_by_id" do
143
+ describe ".find_or_create_by" do
144
144
 
145
145
  before do
146
+ @person = Person.new(:age => 30)
146
147
  @criteria = mock
147
148
  end
148
149
 
149
- it "delegates to find with an id parameter" do
150
- Mongoid::Criteria.expects(:translate).with(Person, :conditions => { "_id" => "1" }).returns(@criteria)
151
- @criteria.expects(:one).returns(Person.new)
152
- Person.find_by_id("1")
150
+ context "when the document is found" do
151
+
152
+ it "returns the document" do
153
+ Mongoid::Criteria.expects(:translate).with(
154
+ Person, :conditions => { :age => 30 }
155
+ ).returns(@criteria)
156
+ @criteria.expects(:one).returns(@person)
157
+ Person.find_or_create_by(:age => 30).should == @person
158
+ end
159
+
160
+ end
161
+
162
+ context "when the document is not found" do
163
+
164
+ it "creates a new document" do
165
+ Mongoid::Criteria.expects(:translate).with(
166
+ Person, :conditions => { :age => 30 }
167
+ ).returns(@criteria)
168
+ @criteria.expects(:one).returns(nil)
169
+ Person.expects(:create).returns(@person)
170
+ person = Person.find_or_create_by(:age => 30)
171
+ person.should be_a_kind_of(Person)
172
+ person.age.should == 30
173
+ end
174
+
175
+ end
176
+
177
+ end
178
+
179
+ describe ".find_or_initialize_by" do
180
+
181
+ before do
182
+ @person = Person.new(:age => 30)
183
+ @criteria = mock
184
+ end
185
+
186
+ context "when the document is found" do
187
+
188
+ it "returns the document" do
189
+ Mongoid::Criteria.expects(:translate).with(
190
+ Person, :conditions => { :age => 30 }
191
+ ).returns(@criteria)
192
+ @criteria.expects(:one).returns(@person)
193
+ Person.find_or_initialize_by(:age => 30).should == @person
194
+ end
195
+
196
+ end
197
+
198
+ context "when the document is not found" do
199
+
200
+ it "returns a new document with the conditions" do
201
+ Mongoid::Criteria.expects(:translate).with(
202
+ Person, :conditions => { :age => 30 }
203
+ ).returns(@criteria)
204
+ @criteria.expects(:one).returns(nil)
205
+ person = Person.find_or_initialize_by(:age => 30)
206
+ person.should be_a_kind_of(Person)
207
+ person.should be_a_new_record
208
+ person.age.should == 30
209
+ end
210
+
153
211
  end
154
212
 
155
213
  end
@@ -211,59 +269,6 @@ describe Mongoid::Finders do
211
269
 
212
270
  end
213
271
 
214
- describe ".method_missing" do
215
-
216
- context "with a finder method name" do
217
-
218
- before do
219
- @criteria = stub
220
- @document = stub
221
- @conditions = { "title" => "Sir", "age" => 30 }
222
- end
223
-
224
- it "executes the finder" do
225
- Mongoid::Criteria.expects(:translate).with(Person, :conditions => @conditions).returns(@criteria)
226
- @criteria.expects(:one).returns(@document)
227
- Person.find_by_title_and_age("Sir", 30)
228
- end
229
-
230
- end
231
-
232
- context "with a finder or creation method name" do
233
-
234
- before do
235
- @criteria = stub
236
- @document = stub
237
- @conditions = { "title" => "Sir", "age" => 30 }
238
- end
239
-
240
- context "when document is found" do
241
-
242
- it "returns the document" do
243
- Mongoid::Criteria.expects(:translate).with(Person, :conditions => @conditions).returns(@criteria)
244
- @criteria.expects(:one).returns(@document)
245
- Person.find_or_initialize_by_title_and_age("Sir", 30).should == @document
246
- end
247
-
248
- end
249
-
250
- context "when document is not found" do
251
-
252
- it "instantiates a new document" do
253
- Mongoid::Criteria.expects(:translate).with(Person, :conditions => @conditions).returns(@criteria)
254
- @criteria.expects(:one).returns(nil)
255
- new_doc = Person.find_or_initialize_by_title_and_age("Sir", 30)
256
- new_doc.new_record?.should be_true
257
- new_doc.title.should == "Sir"
258
- new_doc.age.should == 30
259
- end
260
-
261
- end
262
-
263
- end
264
-
265
- end
266
-
267
272
  describe ".min" do
268
273
 
269
274
  before do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.9
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Durran Jordan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-07 00:00:00 -05:00
12
+ date: 2010-01-08 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -111,7 +111,6 @@ files:
111
111
  - lib/mongoid/config.rb
112
112
  - lib/mongoid/criteria.rb
113
113
  - lib/mongoid/document.rb
114
- - lib/mongoid/dynamic_finder.rb
115
114
  - lib/mongoid/errors.rb
116
115
  - lib/mongoid/extensions.rb
117
116
  - lib/mongoid/extensions/array/accessors.rb
@@ -127,6 +126,7 @@ files:
127
126
  - lib/mongoid/extensions/hash/conversions.rb
128
127
  - lib/mongoid/extensions/hash/criteria_helpers.rb
129
128
  - lib/mongoid/extensions/integer/conversions.rb
129
+ - lib/mongoid/extensions/nil/assimilation.rb
130
130
  - lib/mongoid/extensions/object/conversions.rb
131
131
  - lib/mongoid/extensions/string/conversions.rb
132
132
  - lib/mongoid/extensions/string/inflections.rb
@@ -166,7 +166,6 @@ files:
166
166
  - spec/unit/mongoid/config_spec.rb
167
167
  - spec/unit/mongoid/criteria_spec.rb
168
168
  - spec/unit/mongoid/document_spec.rb
169
- - spec/unit/mongoid/dynamic_finder_spec.rb
170
169
  - spec/unit/mongoid/errors_spec.rb
171
170
  - spec/unit/mongoid/extensions/array/accessors_spec.rb
172
171
  - spec/unit/mongoid/extensions/array/assimilation_spec.rb
@@ -181,6 +180,7 @@ files:
181
180
  - spec/unit/mongoid/extensions/hash/conversions_spec.rb
182
181
  - spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb
183
182
  - spec/unit/mongoid/extensions/integer/conversions_spec.rb
183
+ - spec/unit/mongoid/extensions/nil/assimilation_spec.rb
184
184
  - spec/unit/mongoid/extensions/object/conversions_spec.rb
185
185
  - spec/unit/mongoid/extensions/string/conversions_spec.rb
186
186
  - spec/unit/mongoid/extensions/string/inflections_spec.rb
@@ -247,7 +247,6 @@ test_files:
247
247
  - spec/unit/mongoid/config_spec.rb
248
248
  - spec/unit/mongoid/criteria_spec.rb
249
249
  - spec/unit/mongoid/document_spec.rb
250
- - spec/unit/mongoid/dynamic_finder_spec.rb
251
250
  - spec/unit/mongoid/errors_spec.rb
252
251
  - spec/unit/mongoid/extensions/array/accessors_spec.rb
253
252
  - spec/unit/mongoid/extensions/array/assimilation_spec.rb
@@ -262,6 +261,7 @@ test_files:
262
261
  - spec/unit/mongoid/extensions/hash/conversions_spec.rb
263
262
  - spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb
264
263
  - spec/unit/mongoid/extensions/integer/conversions_spec.rb
264
+ - spec/unit/mongoid/extensions/nil/assimilation_spec.rb
265
265
  - spec/unit/mongoid/extensions/object/conversions_spec.rb
266
266
  - spec/unit/mongoid/extensions/string/conversions_spec.rb
267
267
  - spec/unit/mongoid/extensions/string/inflections_spec.rb
@@ -1,65 +0,0 @@
1
- # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- class DynamicFinder
4
- # Regex for standard dynamic finder methods.
5
- FINDER = /^find_(all_by|last_by|by)_([_a-zA-Z]\w*)$/
6
- # Regex for finder methods that create objects if nothing found.
7
- CREATOR = /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
8
-
9
- attr_reader :conditions, :finder
10
-
11
- # Creates a new DynamicFinder given the supplied method name. This parses
12
- # the name and sets up the appropriate finder type and attribute names in
13
- # order to perform the search.
14
- #
15
- # Options:
16
- #
17
- # method: The name of the dynamic finder method.
18
- #
19
- # Example:
20
- #
21
- # <tt>DynamicFinder.new(:find_by_title_and_age)</tt>
22
- def initialize(method, *args)
23
- @finder, @args = :first, args
24
- case method.to_s
25
- when FINDER
26
- @finder = :all if $1 == "all_by"
27
- @finder = :last if $1 == "last_by"
28
- names = $2
29
- when CREATOR then
30
- @creator = ($1 == "initialize") ? :instantiate : :create
31
- names = $2
32
- else
33
- @finder = nil
34
- end
35
- @attributes = names && names.split("_and_")
36
- generate_conditions
37
- end
38
-
39
- # Will create a new +Document+ based on the type of creator keyword in the
40
- # method, given the supplied class.
41
- #
42
- # Options:
43
- #
44
- # klass: The +Document+ class to be instantiated.
45
- #
46
- # Example:
47
- #
48
- # <tt>finder.create(Person)</tt>
49
- def create(klass)
50
- klass.send(@creator, @conditions) if @creator
51
- end
52
-
53
- protected
54
- def generate_conditions
55
- if @attributes
56
- @conditions = {}.with_indifferent_access
57
- @attributes.each_with_index do |attr, index|
58
- attr = "_id" if attr == "id"
59
- @conditions[attr] = @args[index]
60
- end
61
- end
62
- end
63
-
64
- end
65
- end
@@ -1,145 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::DynamicFinder do
4
-
5
- describe "#conditions" do
6
-
7
- before do
8
- @finder = Mongoid::DynamicFinder.new(:find_by_title_and_age, "Sir", 30)
9
- @conditions = { "title" => "Sir", "age" => 30 }
10
- end
11
-
12
- it "returns the conditions hash for the criteria" do
13
- @finder.conditions.should == @conditions
14
- end
15
-
16
- context "when id is an attribute" do
17
-
18
- before do
19
- @finder = Mongoid::DynamicFinder.new(:find_by_id, "5")
20
- @conditions = { "_id" => "5" }
21
- end
22
-
23
- it "converts to _id" do
24
- @finder.conditions.should == @conditions
25
- end
26
-
27
- end
28
-
29
- end
30
-
31
- describe "#create" do
32
-
33
- context "when initializing" do
34
-
35
- before do
36
- @finder = Mongoid::DynamicFinder.new(:find_or_initialize_by_title_and_age, "Sir", 30)
37
- end
38
-
39
- it "instantiates a new document" do
40
- person = @finder.create(Person)
41
- person.title.should == "Sir"
42
- person.age.should == 30
43
- end
44
-
45
- end
46
-
47
- context "when creating" do
48
-
49
- before do
50
- @finder = Mongoid::DynamicFinder.new(:find_or_create_by_title_and_age, "Sir", 30)
51
- @person = stub
52
- end
53
-
54
- it "creates a new document" do
55
- Person.expects(:create).with(@finder.conditions).returns(@person)
56
- person = @finder.create(Person)
57
- person.should == @person
58
- end
59
-
60
- end
61
-
62
- end
63
-
64
- describe ".initialize" do
65
-
66
- context "when find_by*" do
67
-
68
- before do
69
- @finder = Mongoid::DynamicFinder.new(:find_by_title_and_age, "Sir", 30)
70
- end
71
-
72
- it "sets a first finder and attributes" do
73
- @finder.finder.should == :first
74
- @finder.conditions.should == { "title" => "Sir", "age" => 30 }
75
- end
76
-
77
- end
78
-
79
- context "when find_all_by*" do
80
-
81
- before do
82
- @finder = Mongoid::DynamicFinder.new(:find_all_by_title_and_age, "Sir", 30)
83
- end
84
-
85
- it "sets an all finder and attributes" do
86
- @finder.finder.should == :all
87
- @finder.conditions.should == { "title" => "Sir", "age" => 30 }
88
- end
89
-
90
- end
91
-
92
- context "when find_last_by*" do
93
-
94
- before do
95
- @finder = Mongoid::DynamicFinder.new(:find_last_by_title_and_age, "Sir", 30)
96
- end
97
-
98
- it "sets a last finder and attributes" do
99
- @finder.finder.should == :last
100
- @finder.conditions.should == { "title" => "Sir", "age" => 30 }
101
- end
102
-
103
- end
104
-
105
- context "when find_or_initialize_by*" do
106
-
107
- before do
108
- @finder = Mongoid::DynamicFinder.new(:find_or_initialize_by_title_and_age, "Sir", 30)
109
- end
110
-
111
- it "sets a first finder with attributes or a new" do
112
- @finder.finder.should == :first
113
- @finder.conditions.should == { "title" => "Sir", "age" => 30 }
114
- end
115
-
116
- end
117
-
118
- context "when find_or_create_by*" do
119
-
120
- before do
121
- @finder = Mongoid::DynamicFinder.new(:find_or_create_by_title_and_age, "Sir", 30)
122
- end
123
-
124
- it "sets a first finder with attributes or a create" do
125
- @finder.finder.should == :first
126
- @finder.conditions.should == { "title" => "Sir", "age" => 30 }
127
- end
128
-
129
- end
130
-
131
- context "when invalid finder name" do
132
-
133
- before do
134
- @finder = Mongoid::DynamicFinder.new(:bleh)
135
- end
136
-
137
- it "sets a nil finder" do
138
- @finder.finder.should be_nil
139
- end
140
-
141
- end
142
-
143
- end
144
-
145
- end