mongoid 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/.watchr +20 -2
  2. data/VERSION +1 -1
  3. data/caliper.yml +4 -0
  4. data/lib/mongoid.rb +0 -1
  5. data/lib/mongoid/associations.rb +25 -13
  6. data/lib/mongoid/associations/belongs_to.rb +15 -17
  7. data/lib/mongoid/associations/belongs_to_related.rb +12 -14
  8. data/lib/mongoid/associations/has_many.rb +53 -35
  9. data/lib/mongoid/associations/has_many_related.rb +10 -15
  10. data/lib/mongoid/associations/has_one.rb +31 -30
  11. data/lib/mongoid/associations/has_one_related.rb +18 -20
  12. data/lib/mongoid/associations/options.rb +10 -0
  13. data/lib/mongoid/associations/proxy.rb +18 -1
  14. data/lib/mongoid/criteria.rb +9 -233
  15. data/lib/mongoid/criterion/complex.rb +21 -0
  16. data/lib/mongoid/criterion/exclusion.rb +63 -0
  17. data/lib/mongoid/criterion/inclusion.rb +91 -0
  18. data/lib/mongoid/criterion/optional.rb +96 -0
  19. data/lib/mongoid/document.rb +2 -2
  20. data/lib/mongoid/extensions/hash/accessors.rb +6 -0
  21. data/lib/mongoid/extensions/hash/criteria_helpers.rb +2 -2
  22. data/lib/mongoid/extensions/symbol/inflections.rb +1 -1
  23. data/mongoid.gemspec +53 -3
  24. data/spec/integration/mongoid/associations_spec.rb +41 -0
  25. data/spec/models/address.rb +39 -0
  26. data/spec/models/animal.rb +6 -0
  27. data/spec/models/comment.rb +8 -0
  28. data/spec/models/country_code.rb +6 -0
  29. data/spec/models/employer.rb +5 -0
  30. data/spec/models/game.rb +6 -0
  31. data/spec/models/inheritance.rb +56 -0
  32. data/spec/models/location.rb +5 -0
  33. data/spec/models/mixed_drink.rb +4 -0
  34. data/spec/models/name.rb +13 -0
  35. data/spec/models/namespacing.rb +11 -0
  36. data/spec/models/patient.rb +4 -0
  37. data/spec/models/person.rb +97 -0
  38. data/spec/models/pet.rb +7 -0
  39. data/spec/models/pet_owner.rb +6 -0
  40. data/spec/models/phone.rb +7 -0
  41. data/spec/models/post.rb +15 -0
  42. data/spec/models/translation.rb +5 -0
  43. data/spec/models/vet_visit.rb +5 -0
  44. data/spec/spec_helper.rb +9 -326
  45. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +26 -5
  46. data/spec/unit/mongoid/associations/belongs_to_spec.rb +96 -30
  47. data/spec/unit/mongoid/associations/has_many_related_spec.rb +32 -12
  48. data/spec/unit/mongoid/associations/has_many_spec.rb +48 -12
  49. data/spec/unit/mongoid/associations/has_one_related_spec.rb +29 -4
  50. data/spec/unit/mongoid/associations/has_one_spec.rb +46 -1
  51. data/spec/unit/mongoid/associations/options_spec.rb +58 -0
  52. data/spec/unit/mongoid/associations_spec.rb +58 -1
  53. data/spec/unit/mongoid/criteria_spec.rb +71 -735
  54. data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
  55. data/spec/unit/mongoid/criterion/exclusion_spec.rb +75 -0
  56. data/spec/unit/mongoid/criterion/inclusion_spec.rb +213 -0
  57. data/spec/unit/mongoid/criterion/optional_spec.rb +244 -0
  58. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +20 -0
  59. metadata +53 -3
  60. data/lib/mongoid/complex_criterion.rb +0 -10
@@ -0,0 +1,39 @@
1
+ class Address
2
+ include Mongoid::Document
3
+ field :address_type
4
+ field :number, :type => Integer
5
+ field :street
6
+ field :city
7
+ field :state
8
+ field :post_code
9
+ field :parent_title
10
+ field :services, :type => Array
11
+ key :street
12
+ has_many :locations
13
+
14
+ belongs_to :addressable, :inverse_of => :addresses do
15
+ def extension
16
+ "Testing"
17
+ end
18
+ def doctor?
19
+ title == "Dr"
20
+ end
21
+ end
22
+
23
+ named_scope :rodeo, where(:street => "Rodeo Dr")
24
+
25
+ def set_parent=(set = false)
26
+ self.parent_title = addressable.title if set
27
+ end
28
+
29
+ class << self
30
+ def california
31
+ where(:state => "CA")
32
+ end
33
+
34
+ def homes
35
+ where(:address_type => "Home")
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ class Animal
2
+ include Mongoid::Document
3
+ field :name
4
+ key :name
5
+ belongs_to :person, :inverse_of => :pet
6
+ end
@@ -0,0 +1,8 @@
1
+ class Comment
2
+ include Mongoid::Document
3
+ include Mongoid::Versioning
4
+ include Mongoid::Timestamps
5
+ field :text
6
+ key :text
7
+ validates_presence_of :text
8
+ end
@@ -0,0 +1,6 @@
1
+ class CountryCode
2
+ include Mongoid::Document
3
+ field :code, :type => Integer
4
+ key :code
5
+ belongs_to :phone_number, :inverse_of => :country_codes
6
+ end
@@ -0,0 +1,5 @@
1
+ class Employer
2
+ def id
3
+ "1"
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class Game
2
+ include Mongoid::Document
3
+ field :high_score, :default => 500
4
+ field :score, :type => Integer, :default => 0
5
+ belongs_to_related :person
6
+ end
@@ -0,0 +1,56 @@
1
+ class Canvas
2
+ include Mongoid::Document
3
+ field :name
4
+ has_many :shapes
5
+ has_one :writer
6
+
7
+ def render
8
+ shapes.each { |shape| render }
9
+ end
10
+ end
11
+
12
+ class Browser < Canvas
13
+ field :version, :type => Integer
14
+ def render; end
15
+ end
16
+
17
+ class Firefox < Browser
18
+ field :user_agent
19
+ def render; end
20
+ end
21
+
22
+ class Shape
23
+ include Mongoid::Document
24
+ field :x, :type => Integer, :default => 0
25
+ field :y, :type => Integer, :default => 0
26
+
27
+ belongs_to :canvas, :inverse_of => :shapes
28
+
29
+ def render; end
30
+ end
31
+
32
+ class Square < Shape
33
+ field :width, :type => Integer, :default => 0
34
+ field :height, :type => Integer, :default => 0
35
+ end
36
+
37
+ class Circle < Shape
38
+ field :radius, :type => Integer, :default => 0
39
+ end
40
+
41
+ class Writer
42
+ include Mongoid::Document
43
+ field :speed, :type => Integer, :default => 0
44
+
45
+ belongs_to :canvas, :inverse_of => :writer
46
+
47
+ def write; end
48
+ end
49
+
50
+ class HtmlWriter < Writer
51
+ def write; end
52
+ end
53
+
54
+ class PdfWriter < Writer
55
+ def write; end
56
+ end
@@ -0,0 +1,5 @@
1
+ class Location
2
+ include Mongoid::Document
3
+ field :name
4
+ belongs_to :address, :inverse_of => :locations
5
+ end
@@ -0,0 +1,4 @@
1
+ class MixedDrink
2
+ include Mongoid::Document
3
+ field :name
4
+ end
@@ -0,0 +1,13 @@
1
+ class Name
2
+ include Mongoid::Document
3
+ field :first_name
4
+ field :last_name
5
+ field :parent_title
6
+ key :first_name, :last_name
7
+ has_many :translations
8
+ belongs_to :person, :inverse_of => :name
9
+
10
+ def set_parent=(set = false)
11
+ self.parent_title = person.title if set
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module Medical
2
+ class Patient
3
+ include Mongoid::Document
4
+ field :name
5
+ has_many :prescriptions, :class_name => "Medical::Prescription"
6
+ end
7
+ class Prescription
8
+ include Mongoid::Document
9
+ field :name
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ class Patient
2
+ include Mongoid::Document
3
+ store_in :inpatient
4
+ end
@@ -0,0 +1,97 @@
1
+ class Person
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+
5
+ field :title
6
+ field :terms, :type => Boolean
7
+ field :age, :type => Integer, :default => 100
8
+ field :dob, :type => Date
9
+ field :mixed_drink, :type => MixedDrink
10
+ field :employer_id
11
+ field :lunch_time, :type => Time
12
+ field :aliases, :type => Array
13
+ field :map, :type => Hash
14
+ field :score, :type => Integer
15
+ field :blood_alcohol_content, :type => Float, :default => lambda{ 0.0 }
16
+ field :ssn
17
+
18
+ index :age
19
+ index :addresses
20
+ index :dob
21
+ index :name
22
+ index :title
23
+ index :ssn, :unique => true
24
+
25
+ attr_reader :rescored
26
+
27
+ has_many :addresses do
28
+ def extension
29
+ "Testing"
30
+ end
31
+ def find_by_street(street)
32
+ @target.select { |doc| doc.street == street }
33
+ end
34
+ end
35
+
36
+ has_many :phone_numbers, :class_name => "Phone"
37
+
38
+ has_one :name do
39
+ def extension
40
+ "Testing"
41
+ end
42
+ def dawkins?
43
+ first_name == "Richard" && last_name == "Dawkins"
44
+ end
45
+ end
46
+
47
+ has_one :pet, :class_name => "Animal"
48
+
49
+ accepts_nested_attributes_for :addresses, :reject_if => lambda { |attrs| attrs["street"].blank? }
50
+ accepts_nested_attributes_for :name
51
+
52
+ has_one_related :game do
53
+ def extension
54
+ "Testing"
55
+ end
56
+ end
57
+
58
+ has_many_related :posts do
59
+ def extension
60
+ "Testing"
61
+ end
62
+ end
63
+
64
+ def score_with_rescoring=(score)
65
+ @rescored = score.to_i + 20
66
+ self.score_without_rescoring = score
67
+ end
68
+
69
+ alias_method_chain :score=, :rescoring
70
+
71
+ def update_addresses
72
+ addresses.each do |address|
73
+ address.street = "Updated Address"
74
+ end
75
+ end
76
+
77
+ def employer=(emp)
78
+ self.employer_id = emp.id
79
+ end
80
+
81
+ class << self
82
+ def accepted
83
+ criteria.where(:terms => true)
84
+ end
85
+ def knight
86
+ criteria.where(:title => "Sir")
87
+ end
88
+ def old
89
+ criteria.where(:age => { "$gt" => 50 })
90
+ end
91
+ end
92
+
93
+ end
94
+
95
+ class Doctor < Person
96
+ field :specialty
97
+ end
@@ -0,0 +1,7 @@
1
+ class Pet
2
+ include Mongoid::Document
3
+ field :name
4
+ field :weight, :type => Float, :default => 0.0
5
+ has_many :vet_visits
6
+ belongs_to :pet_owner, :inverse_of => :pet
7
+ end
@@ -0,0 +1,6 @@
1
+ class PetOwner
2
+ include Mongoid::Document
3
+ field :title
4
+ has_one :pet
5
+ has_one :address
6
+ end
@@ -0,0 +1,7 @@
1
+ class Phone
2
+ include Mongoid::Document
3
+ field :number
4
+ key :number
5
+ belongs_to :person, :inverse_of => :phone_numbers
6
+ has_one :country_code
7
+ end
@@ -0,0 +1,15 @@
1
+ class Post
2
+ include Mongoid::Document
3
+ include Mongoid::Versioning
4
+ include Mongoid::Timestamps
5
+ field :title
6
+ belongs_to_related :person
7
+
8
+ named_scope :recent, where(:created_at => { "$lt" => Time.now, "$gt" => 30.days.ago })
9
+
10
+ class << self
11
+ def old
12
+ where(:created_at => { "$lt" => 30.days.ago })
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ class Translation
2
+ include Mongoid::Document
3
+ field :language
4
+ belongs_to :name, :inverse_of => :translations
5
+ end
@@ -0,0 +1,5 @@
1
+ class VetVisit
2
+ include Mongoid::Document
3
+ field :date, :type => Date
4
+ belongs_to :pet, :inverse_of => :vet_visits
5
+ end
@@ -1,5 +1,9 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
3
+
4
+ MODELS = File.join(File.dirname(__FILE__), "models")
5
+ $LOAD_PATH.unshift(MODELS)
6
+
3
7
  require 'rubygems'
4
8
 
5
9
  gem "mocha", ">= 0.9.8"
@@ -8,8 +12,11 @@ require "mocha"
8
12
  require "mongoid"
9
13
  require "spec"
10
14
 
11
- connection = Mongo::Connection.new
12
- Mongoid.database = connection.db("mongoid_test")
15
+ Mongoid.config do |config|
16
+ config.database = Mongo::Connection.new.db("mongoid_test")
17
+ end
18
+
19
+ Dir[File.join(MODELS, "*.rb")].each {|file| require File.basename(file) }
13
20
 
14
21
  Spec::Runner.configure do |config|
15
22
  config.mock_with :mocha
@@ -17,327 +24,3 @@ Spec::Runner.configure do |config|
17
24
  Mongoid.database.collections.each(&:drop)
18
25
  end
19
26
  end
20
-
21
- class MixedDrink
22
- include Mongoid::Document
23
- field :name
24
- end
25
-
26
- class Person
27
- include Mongoid::Document
28
- include Mongoid::Timestamps
29
-
30
- field :title
31
- field :terms, :type => Boolean
32
- field :age, :type => Integer, :default => 100
33
- field :dob, :type => Date
34
- field :mixed_drink, :type => MixedDrink
35
- field :employer_id
36
- field :lunch_time, :type => Time
37
- field :aliases, :type => Array
38
- field :map, :type => Hash
39
- field :score, :type => Integer
40
- field :blood_alcohol_content, :type => Float, :default => lambda{ 0.0 }
41
- field :ssn
42
-
43
- index :age
44
- index :addresses
45
- index :dob
46
- index :name
47
- index :title
48
- index :ssn, :unique => true
49
-
50
- attr_reader :rescored
51
-
52
- has_many :addresses
53
- has_many :phone_numbers, :class_name => "Phone"
54
-
55
- has_one :name
56
- has_one :pet, :class_name => "Animal"
57
-
58
- accepts_nested_attributes_for :addresses, :reject_if => lambda { |attrs| attrs["street"].blank? }
59
- accepts_nested_attributes_for :name
60
-
61
- has_one_related :game
62
- has_many_related :posts
63
-
64
- def score_with_rescoring=(score)
65
- @rescored = score.to_i + 20
66
- self.score_without_rescoring = score
67
- end
68
-
69
- alias_method_chain :score=, :rescoring
70
-
71
- def update_addresses
72
- addresses.each do |address|
73
- address.street = "Updated Address"
74
- end
75
- end
76
-
77
- def employer=(emp)
78
- self.employer_id = emp.id
79
- end
80
-
81
- class << self
82
- def accepted
83
- criteria.where(:terms => true)
84
- end
85
- def knight
86
- criteria.where(:title => "Sir")
87
- end
88
- def old
89
- criteria.where(:age => { "$gt" => 50 })
90
- end
91
- end
92
-
93
- end
94
-
95
- class Doctor < Person
96
- field :specialty
97
- end
98
-
99
- class Employer
100
- def id
101
- "1"
102
- end
103
- end
104
-
105
- class CountryCode
106
- include Mongoid::Document
107
- field :code, :type => Integer
108
- key :code
109
- belongs_to :phone_number, :inverse_of => :country_codes
110
- end
111
-
112
- class Phone
113
- include Mongoid::Document
114
- field :number
115
- key :number
116
- belongs_to :person, :inverse_of => :phone_numbers
117
- has_one :country_code
118
- end
119
-
120
- class Animal
121
- include Mongoid::Document
122
- field :name
123
- key :name
124
- belongs_to :person, :inverse_of => :pet
125
- end
126
-
127
- class PetOwner
128
- include Mongoid::Document
129
- field :title
130
- has_one :pet
131
- has_one :address
132
- end
133
-
134
- class Pet
135
- include Mongoid::Document
136
- field :name
137
- field :weight, :type => Float, :default => 0.0
138
- has_many :vet_visits
139
- belongs_to :pet_owner, :inverse_of => :pet
140
- end
141
-
142
- class VetVisit
143
- include Mongoid::Document
144
- field :date, :type => Date
145
- belongs_to :pet, :inverse_of => :vet_visits
146
- end
147
-
148
- class Address
149
- include Mongoid::Document
150
- field :address_type
151
- field :number, :type => Integer
152
- field :street
153
- field :city
154
- field :state
155
- field :post_code
156
- field :parent_title
157
- field :services, :type => Array
158
- key :street
159
- has_many :locations
160
- belongs_to :addressable, :inverse_of => :addresses
161
-
162
- named_scope :rodeo, where(:street => "Rodeo Dr")
163
-
164
- def set_parent=(set = false)
165
- self.parent_title = addressable.title if set
166
- end
167
-
168
- class << self
169
- def california
170
- where(:state => "CA")
171
- end
172
-
173
- def homes
174
- where(:address_type => "Home")
175
- end
176
-
177
- end
178
- end
179
-
180
- class Location
181
- include Mongoid::Document
182
- field :name
183
- belongs_to :address, :inverse_of => :locations
184
- end
185
-
186
- class Name
187
- include Mongoid::Document
188
- field :first_name
189
- field :last_name
190
- field :parent_title
191
- key :first_name, :last_name
192
- has_many :translations
193
- belongs_to :person, :inverse_of => :name
194
-
195
- def set_parent=(set = false)
196
- self.parent_title = person.title if set
197
- end
198
- end
199
-
200
- class Translation
201
- include Mongoid::Document
202
- field :language
203
- belongs_to :name, :inverse_of => :translations
204
- end
205
-
206
- class Comment
207
- include Mongoid::Document
208
- include Mongoid::Versioning
209
- include Mongoid::Timestamps
210
- field :text
211
- key :text
212
- validates_presence_of :text
213
- end
214
-
215
- class Post
216
- include Mongoid::Document
217
- include Mongoid::Versioning
218
- include Mongoid::Timestamps
219
- field :title
220
- belongs_to_related :person
221
-
222
- named_scope :recent, where(:created_at => { "$lt" => Time.now, "$gt" => 30.days.ago })
223
-
224
- class << self
225
- def old
226
- where(:created_at => { "$lt" => 30.days.ago })
227
- end
228
- end
229
- end
230
-
231
- class Game
232
- include Mongoid::Document
233
- field :high_score, :default => 500
234
- field :score, :type => Integer, :default => 0
235
- belongs_to_related :person
236
- end
237
-
238
- class Patient
239
- include Mongoid::Document
240
- store_in :inpatient
241
- end
242
-
243
- if RUBY_VERSION == '1.8.6'
244
- class Array
245
- alias :count :size
246
- end
247
- end
248
-
249
- class Object
250
- def tapp
251
- tap do
252
- puts "#{File.basename caller[2]}: #{self.inspect}"
253
- end
254
- end
255
- end
256
-
257
- # Inhertiance test models:
258
- class Canvas
259
- include Mongoid::Document
260
- field :name
261
- has_many :shapes
262
- has_one :writer
263
-
264
- def render
265
- shapes.each { |shape| render }
266
- end
267
- end
268
-
269
- class Browser < Canvas
270
- field :version, :type => Integer
271
- def render; end
272
- end
273
-
274
- class Firefox < Browser
275
- field :user_agent
276
- def render; end
277
- end
278
-
279
- class Writer
280
- include Mongoid::Document
281
- field :speed, :type => Integer, :default => 0
282
-
283
- belongs_to :canvas, :inverse_of => :writer
284
-
285
- def write; end
286
- end
287
-
288
- class HtmlWriter < Writer
289
- def write; end
290
- end
291
-
292
- class PdfWriter < Writer
293
- def write; end
294
- end
295
-
296
- class Shape
297
- include Mongoid::Document
298
- field :x, :type => Integer, :default => 0
299
- field :y, :type => Integer, :default => 0
300
-
301
- belongs_to :canvas, :inverse_of => :shapes
302
-
303
- def render; end
304
- end
305
-
306
- class Square < Shape
307
- field :width, :type => Integer, :default => 0
308
- field :height, :type => Integer, :default => 0
309
- end
310
-
311
- class Circle < Shape
312
- field :radius, :type => Integer, :default => 0
313
- end
314
-
315
- # Namespacing test models:
316
- module Medical
317
- class Patient
318
- include Mongoid::Document
319
- field :name
320
- has_many :prescriptions, :class_name => "Medical::Prescription"
321
- end
322
-
323
- class Prescription
324
- include Mongoid::Document
325
- field :name
326
- end
327
- end
328
-
329
- ###################################
330
-
331
- class Author
332
- include Mongoid::Document
333
- field :name
334
- has_many :books
335
- end
336
-
337
- class Book
338
- include Mongoid::Document
339
- field :title
340
- belongs_to :author, :inverse_of => :books
341
- end
342
-
343
-