mongoid 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.watchr +20 -2
- data/VERSION +1 -1
- data/caliper.yml +4 -0
- data/lib/mongoid.rb +0 -1
- data/lib/mongoid/associations.rb +25 -13
- data/lib/mongoid/associations/belongs_to.rb +15 -17
- data/lib/mongoid/associations/belongs_to_related.rb +12 -14
- data/lib/mongoid/associations/has_many.rb +53 -35
- data/lib/mongoid/associations/has_many_related.rb +10 -15
- data/lib/mongoid/associations/has_one.rb +31 -30
- data/lib/mongoid/associations/has_one_related.rb +18 -20
- data/lib/mongoid/associations/options.rb +10 -0
- data/lib/mongoid/associations/proxy.rb +18 -1
- data/lib/mongoid/criteria.rb +9 -233
- data/lib/mongoid/criterion/complex.rb +21 -0
- data/lib/mongoid/criterion/exclusion.rb +63 -0
- data/lib/mongoid/criterion/inclusion.rb +91 -0
- data/lib/mongoid/criterion/optional.rb +96 -0
- data/lib/mongoid/document.rb +2 -2
- data/lib/mongoid/extensions/hash/accessors.rb +6 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +2 -2
- data/lib/mongoid/extensions/symbol/inflections.rb +1 -1
- data/mongoid.gemspec +53 -3
- data/spec/integration/mongoid/associations_spec.rb +41 -0
- data/spec/models/address.rb +39 -0
- data/spec/models/animal.rb +6 -0
- data/spec/models/comment.rb +8 -0
- data/spec/models/country_code.rb +6 -0
- data/spec/models/employer.rb +5 -0
- data/spec/models/game.rb +6 -0
- data/spec/models/inheritance.rb +56 -0
- data/spec/models/location.rb +5 -0
- data/spec/models/mixed_drink.rb +4 -0
- data/spec/models/name.rb +13 -0
- data/spec/models/namespacing.rb +11 -0
- data/spec/models/patient.rb +4 -0
- data/spec/models/person.rb +97 -0
- data/spec/models/pet.rb +7 -0
- data/spec/models/pet_owner.rb +6 -0
- data/spec/models/phone.rb +7 -0
- data/spec/models/post.rb +15 -0
- data/spec/models/translation.rb +5 -0
- data/spec/models/vet_visit.rb +5 -0
- data/spec/spec_helper.rb +9 -326
- data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +26 -5
- data/spec/unit/mongoid/associations/belongs_to_spec.rb +96 -30
- data/spec/unit/mongoid/associations/has_many_related_spec.rb +32 -12
- data/spec/unit/mongoid/associations/has_many_spec.rb +48 -12
- data/spec/unit/mongoid/associations/has_one_related_spec.rb +29 -4
- data/spec/unit/mongoid/associations/has_one_spec.rb +46 -1
- data/spec/unit/mongoid/associations/options_spec.rb +58 -0
- data/spec/unit/mongoid/associations_spec.rb +58 -1
- data/spec/unit/mongoid/criteria_spec.rb +71 -735
- data/spec/unit/mongoid/criterion/complex_spec.rb +19 -0
- data/spec/unit/mongoid/criterion/exclusion_spec.rb +75 -0
- data/spec/unit/mongoid/criterion/inclusion_spec.rb +213 -0
- data/spec/unit/mongoid/criterion/optional_spec.rb +244 -0
- data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +20 -0
- metadata +53 -3
- 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
|
data/spec/models/game.rb
ADDED
@@ -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
|
data/spec/models/name.rb
ADDED
@@ -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,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
|
data/spec/models/pet.rb
ADDED
data/spec/models/post.rb
ADDED
@@ -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
|
data/spec/spec_helper.rb
CHANGED
@@ -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
|
-
|
12
|
-
|
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
|
-
|