mongoid 0.11.9 → 0.12.0

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