mongoid 0.3.4 → 0.4.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/README.textile +7 -13
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/lib/mongoid/criteria.rb +209 -29
- data/lib/mongoid/document.rb +1 -2
- data/mongoid.gemspec +3 -3
- data/spec/unit/mongoid/criteria_spec.rb +4 -2
- data/spec/unit/mongoid/document_spec.rb +2 -2
- metadata +3 -3
data/README.textile
CHANGED
@@ -3,26 +3,19 @@
|
|
3
3
|
<h3>About Mongoid</h3>
|
4
4
|
|
5
5
|
<p>
|
6
|
-
Mongoid is an ODM (Object-Document-Mapper) framework for MongoDB in Ruby.
|
7
|
-
mapping frameworks in that it constrains the models into behaving in a manner appropriate for a
|
8
|
-
document database. That is to say there are no relationships between documents in the underlying datastore.
|
9
|
-
If a relationship is set up in the Model the child models are automatically embedded within the parent document
|
10
|
-
in the database. The concept of a foreign key relationship to another Document does not exist, as that is
|
11
|
-
design and thinking for a relational database, not a document database. Mongoloid does however provide
|
12
|
-
all the ActiveRecord style functionality you need, with the difference that it stores all associations
|
13
|
-
within the parent document.
|
6
|
+
Mongoid is an ODM (Object-Document-Mapper) framework for MongoDB in Ruby.
|
14
7
|
</p>
|
15
8
|
|
16
9
|
<h3>Project Tracking</h3>
|
17
10
|
|
18
11
|
<a href="http://www.pivotaltracker.com/projects/27482">Mongoid on Pivotal Tracker</a>
|
19
12
|
<a href="http://groups.google.com/group/mongoid">Mongoid Google Group</a>
|
20
|
-
<a href="http://
|
13
|
+
<a href="http://mongoid.org:4444/">Mongoid on CI Joe</a>
|
21
14
|
|
22
15
|
<h3>Compatibility</h3>
|
23
16
|
|
24
17
|
<p>
|
25
|
-
Mongoid is developed against Ruby 1.8.6, 1.8.7, 1.9.1
|
18
|
+
Mongoid is developed against Ruby 1.8.6, 1.8.7, 1.9.1, 1.9.2
|
26
19
|
</p>
|
27
20
|
|
28
21
|
<h2>Mongoid in Action</h2>
|
@@ -55,6 +48,7 @@ Example of a simple domain model:
|
|
55
48
|
fields \
|
56
49
|
:first_name,
|
57
50
|
:last_name
|
51
|
+
has_timestamps
|
58
52
|
end
|
59
53
|
</pre>
|
60
54
|
|
@@ -85,15 +79,15 @@ Update a Document:
|
|
85
79
|
Search for a Document in the database:
|
86
80
|
|
87
81
|
<pre>
|
88
|
-
Person.find(:all, :title => "Esquire")
|
82
|
+
Person.find(:all, :conditions => {:title => "Esquire"})
|
89
83
|
|
90
|
-
Person.find(:first, :title => "Esquire")
|
84
|
+
Person.find(:first, :conditions => {:title => "Esquire"})
|
91
85
|
</pre>
|
92
86
|
|
93
87
|
Paginate Document search results:
|
94
88
|
|
95
89
|
<pre>
|
96
|
-
Person.paginate(:title => "Esquire", :page => 1, :per_page => 20)
|
90
|
+
Person.paginate(:conditions => {:title => "Esquire"}, :page => 1, :per_page => 20)
|
97
91
|
</pre>
|
98
92
|
|
99
93
|
Validations:
|
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ begin
|
|
8
8
|
require "jeweler"
|
9
9
|
Jeweler::Tasks.new do |gem|
|
10
10
|
gem.name = "mongoid"
|
11
|
-
gem.summary =
|
11
|
+
gem.summary = "ODM framework for MongoDB"
|
12
12
|
gem.email = "durran@gmail.com"
|
13
13
|
gem.homepage = "http://github.com/durran/mongoid"
|
14
14
|
gem.authors = ["Durran Jordan"]
|
@@ -37,13 +37,13 @@ end
|
|
37
37
|
|
38
38
|
Rake::RDocTask.new do |rdoc|
|
39
39
|
if File.exist?("VERSION.yml")
|
40
|
-
config =
|
40
|
+
config = File.read("VERSION")
|
41
41
|
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
42
42
|
else
|
43
43
|
version = ""
|
44
44
|
end
|
45
45
|
rdoc.rdoc_dir = "rdoc"
|
46
|
-
rdoc.title = "
|
46
|
+
rdoc.title = "mongoid #{version}"
|
47
47
|
rdoc.rdoc_files.include("README*")
|
48
48
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
49
49
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -1,85 +1,265 @@
|
|
1
1
|
module Mongoid #:nodoc:
|
2
|
-
|
2
|
+
# The +Criteria+ class is the core object needed in Mongoid to retrieve
|
3
|
+
# objects from the database. It is a DSL that essentially sets up the
|
4
|
+
# selector and options arguments that get passed on to a <tt>Mongo::Collection</tt>
|
5
|
+
# in the Ruby driver. Each method on the +Criteria+ returns self to they
|
6
|
+
# can be chained in order to create a readable criterion to be executed
|
7
|
+
# against the database.
|
8
|
+
#
|
9
|
+
# Example setup:
|
10
|
+
#
|
11
|
+
# <tt>criteria = Criteria.new</tt>
|
12
|
+
#
|
13
|
+
# <tt>criteria.select(:field => "value").only(:field).skip(20).limit(20)</tt>
|
14
|
+
#
|
15
|
+
# <tt>criteria.execute</tt>
|
16
|
+
class Criteria
|
3
17
|
attr_reader :selector, :options, :type
|
4
18
|
|
5
|
-
#
|
6
|
-
#
|
19
|
+
# Adds a criterion to the +Criteria+ that specifies values that must all
|
20
|
+
# be matched in order to return results. Similar to an "in" clause but the
|
21
|
+
# underlying conditional logic is an "AND" and not an "OR". The MongoDB
|
22
|
+
# conditional operator that will be used is "$all".
|
23
|
+
#
|
24
|
+
# Options:
|
25
|
+
#
|
26
|
+
# selections: A +Hash+ where the key is the field name and the value is an
|
27
|
+
# +Array+ of values that must all match.
|
28
|
+
#
|
29
|
+
# Example:
|
30
|
+
#
|
31
|
+
# <tt>criteria.all(:field => ["value1", "value2"])</tt>
|
32
|
+
#
|
33
|
+
# <tt>criteria.all(:field1 => ["value1", "value2"], :field2 => ["value1"])</tt>
|
34
|
+
#
|
35
|
+
# Returns: <tt>self</tt>
|
7
36
|
def all(selections = {})
|
8
37
|
selections.each { |key, value| @selector[key] = { "$all" => value } }; self
|
9
38
|
end
|
10
39
|
|
11
|
-
#
|
40
|
+
# Adds a criterion to the +Criteria+ that specifies values that are not allowed
|
41
|
+
# to match any document in the database. The MongoDB conditional operator that
|
42
|
+
# will be used is "$ne".
|
43
|
+
#
|
44
|
+
# Options:
|
45
|
+
#
|
46
|
+
# excludes: A +Hash+ where the key is the field name and the value is a
|
47
|
+
# value that must not be equal to the corresponding field value in the database.
|
48
|
+
#
|
49
|
+
# Example:
|
50
|
+
#
|
51
|
+
# <tt>criteria.excludes(:field => "value1")</tt>
|
52
|
+
#
|
53
|
+
# <tt>criteria.excludes(:field1 => "value1", :field2 => "value1")</tt>
|
54
|
+
#
|
55
|
+
# Returns: <tt>self</tt>
|
12
56
|
def excludes(exclusions = {})
|
13
57
|
exclusions.each { |key, value| @selector[key] = { "$ne" => value } }; self
|
14
58
|
end
|
15
59
|
|
16
|
-
# Execute the criteria
|
17
|
-
# the collection.
|
18
|
-
|
19
|
-
|
20
|
-
|
60
|
+
# Execute the criteria. This will take the internally built selector and options
|
61
|
+
# and pass them on to the Ruby driver's +find()+ method on the collection. The
|
62
|
+
# collection itself will be retrieved from the class provided, and once the
|
63
|
+
# query has returned new documents of the type of class provided will be instantiated.
|
64
|
+
#
|
65
|
+
# If this is a +Criteria+ to only find the first object, this will return a
|
66
|
+
# single object of the type of class provided.
|
67
|
+
#
|
68
|
+
# If this is a +Criteria+ to find multiple results, will return an +Array+ of
|
69
|
+
# objects of the type of class provided.
|
70
|
+
def execute(klass)
|
71
|
+
return klass.new(klass.collection.find_one(@selector, @options)) if type == :first
|
72
|
+
return klass.collection.find(@selector, @options).collect { |doc| klass.new(doc) }
|
21
73
|
end
|
22
74
|
|
23
|
-
#
|
24
|
-
#
|
75
|
+
# Adds a criterion to the +Criteria+ that specifies values where any can
|
76
|
+
# be matched in order to return results. This is similar to an SQL "IN"
|
77
|
+
# clause. The MongoDB conditional operator that will be used is "$in".
|
78
|
+
#
|
79
|
+
# Options:
|
80
|
+
#
|
81
|
+
# inclusions: A +Hash+ where the key is the field name and the value is an
|
82
|
+
# +Array+ of values that any can match.
|
83
|
+
#
|
84
|
+
# Example:
|
85
|
+
#
|
86
|
+
# <tt>criteria.in(:field => ["value1", "value2"])</tt>
|
87
|
+
#
|
88
|
+
# <tt>criteria.in(:field1 => ["value1", "value2"], :field2 => ["value1"])</tt>
|
89
|
+
#
|
90
|
+
# Returns: <tt>self</tt>
|
25
91
|
def in(inclusions = {})
|
26
92
|
inclusions.each { |key, value| @selector[key] = { "$in" => value } }; self
|
27
93
|
end
|
28
94
|
|
29
|
-
# Adds
|
95
|
+
# Adds a criterion to the +Criteria+ that specifies an id that must be matched.
|
96
|
+
#
|
97
|
+
# Options:
|
98
|
+
#
|
99
|
+
# object_id: A +String+ representation of a <tt>Mongo::ObjectID</tt>
|
100
|
+
#
|
101
|
+
# Example:
|
102
|
+
#
|
103
|
+
# <tt>criteria.id("4ab2bc4b8ad548971900005c")</tt>
|
104
|
+
#
|
105
|
+
# Returns: <tt>self</tt>
|
30
106
|
def id(object_id)
|
31
107
|
@selector[:_id] = Mongo::ObjectID.from_string(object_id); self
|
32
108
|
end
|
33
109
|
|
34
|
-
# Create the new Criteria object.
|
35
|
-
#
|
36
|
-
#
|
110
|
+
# Create the new +Criteria+ object. This will initialize the selector
|
111
|
+
# and options hashes, as well as the type of criteria.
|
112
|
+
#
|
113
|
+
# Options:
|
114
|
+
#
|
115
|
+
# type: One of :all, :first:, or :last
|
37
116
|
def initialize(type)
|
38
117
|
@selector, @options, @type = {}, {}, type
|
39
118
|
end
|
40
119
|
|
41
|
-
#
|
42
|
-
# conjunction with skip()
|
120
|
+
# Adds a criterion to the +Criteria+ that specifies the maximum number of
|
121
|
+
# results to return. This is mostly used in conjunction with <tt>skip()</tt>
|
122
|
+
# to handle paginated results.
|
123
|
+
#
|
124
|
+
# Options:
|
125
|
+
#
|
126
|
+
# value: An +Integer+ specifying the max number of results. Defaults to 20.
|
127
|
+
#
|
128
|
+
# Example:
|
129
|
+
#
|
130
|
+
# <tt>criteria.limit(100)</tt>
|
131
|
+
#
|
132
|
+
# Returns: <tt>self</tt>
|
43
133
|
def limit(value = 20)
|
44
134
|
@options[:limit] = value; self
|
45
135
|
end
|
46
136
|
|
47
|
-
#
|
48
|
-
#
|
49
|
-
# This is
|
137
|
+
# Adds a criterion to the +Criteria+ that specifies values that must
|
138
|
+
# be matched in order to return results. This is similar to a SQL "WHERE"
|
139
|
+
# clause. This is the actual selector that will be provided to MongoDB,
|
140
|
+
# similar to the Javascript object that is used when performing a find()
|
141
|
+
# in the MongoDB console.
|
142
|
+
#
|
143
|
+
# Options:
|
144
|
+
#
|
145
|
+
# selectior: A +Hash+ that must match the attributes of the +Document+.
|
146
|
+
#
|
147
|
+
# Example:
|
148
|
+
#
|
149
|
+
# <tt>criteria.select(:field1 => "value1", :field2 => 15)</tt>
|
150
|
+
#
|
151
|
+
# Returns: <tt>self</tt>
|
50
152
|
def select(selector = {})
|
51
153
|
@selector = selector; self
|
52
154
|
end
|
53
155
|
|
54
|
-
#
|
156
|
+
# Adds a criterion to the +Criteria+ that specifies values where none
|
157
|
+
# should match in order to return results. This is similar to an SQL "NOT IN"
|
158
|
+
# clause. The MongoDB conditional operator that will be used is "$nin".
|
159
|
+
#
|
160
|
+
# Options:
|
161
|
+
#
|
162
|
+
# exclusions: A +Hash+ where the key is the field name and the value is an
|
163
|
+
# +Array+ of values that none can match.
|
164
|
+
#
|
165
|
+
# Example:
|
166
|
+
#
|
167
|
+
# <tt>criteria.not_in(:field => ["value1", "value2"])</tt>
|
168
|
+
#
|
169
|
+
# <tt>criteria.not_in(:field1 => ["value1", "value2"], :field2 => ["value1"])</tt>
|
170
|
+
#
|
171
|
+
# Returns: <tt>self</tt>
|
55
172
|
def not_in(exclusions)
|
56
173
|
exclusions.each { |key, value| @selector[key] = { "$nin" => value } }; self
|
57
174
|
end
|
58
175
|
|
59
|
-
#
|
176
|
+
# Adds a criterion to the +Criteria+ that specifies additional options
|
177
|
+
# to be passed to the Ruby driver, in the exact format for the driver.
|
178
|
+
#
|
179
|
+
# Options:
|
180
|
+
#
|
181
|
+
# extras: A +Hash+ that gets set to the driver options.
|
182
|
+
#
|
183
|
+
# Example:
|
184
|
+
#
|
185
|
+
# <tt>criteria.extras(:limit => 20, :skip => 40)</tt>
|
186
|
+
#
|
187
|
+
# Returns: <tt>self</tt>
|
60
188
|
def extras(extras)
|
61
189
|
@options = extras; self
|
62
190
|
end
|
63
191
|
|
64
|
-
#
|
65
|
-
#
|
192
|
+
# Adds a criterion to the +Criteria+ that specifies the sort order of
|
193
|
+
# the returned documents in the database. Similar to a SQL "ORDER BY".
|
194
|
+
#
|
195
|
+
# Options:
|
196
|
+
#
|
197
|
+
# params: A +Hash+ where the key is the field name and the value is an
|
198
|
+
# integer specifying the direction: 1 for ascending, -1 for descending.
|
199
|
+
#
|
200
|
+
# Example:
|
201
|
+
#
|
202
|
+
# <tt>criteria.order_by(:field1 => 1, :field2 => -1)</tt>
|
203
|
+
#
|
204
|
+
# Returns: <tt>self</tt>
|
66
205
|
def order_by(params = {})
|
67
206
|
@options[:sort] = params; self
|
68
207
|
end
|
69
208
|
|
70
|
-
#
|
71
|
-
#
|
209
|
+
# Adds a criterion to the +Criteria+ that specifies the fields that will
|
210
|
+
# get returned from the Document. Used mainly for list views that do not
|
211
|
+
# require all fields to be present. This is similar to SQL "SELECT" values.
|
212
|
+
#
|
213
|
+
# Options:
|
214
|
+
#
|
215
|
+
# params: A list of field names to retrict the returned fields to.
|
216
|
+
#
|
217
|
+
# Example:
|
218
|
+
#
|
219
|
+
# <tt>criteria.only(:field1, :field2, :field3)</tt>
|
220
|
+
#
|
221
|
+
# Returns: <tt>self</tt>
|
72
222
|
def only(*args)
|
73
223
|
@options[:fields] = args.flatten; self
|
74
224
|
end
|
75
225
|
|
76
|
-
#
|
77
|
-
#
|
226
|
+
# Adds a criterion to the +Criteria+ that specifies how many results to skip
|
227
|
+
# when returning Documents. This is mostly used in conjunction with
|
228
|
+
# <tt>limit()</tt> to handle paginated results, and is similar to the
|
229
|
+
# traditional "offset" parameter.
|
230
|
+
#
|
231
|
+
# Options:
|
232
|
+
#
|
233
|
+
# value: An +Integer+ specifying the number of results to skip. Defaults to 0.
|
234
|
+
#
|
235
|
+
# Example:
|
236
|
+
#
|
237
|
+
# <tt>criteria.skip(20)</tt>
|
238
|
+
#
|
239
|
+
# Returns: <tt>self</tt>
|
78
240
|
def skip(value = 0)
|
79
241
|
@options[:skip] = value; self
|
80
242
|
end
|
81
243
|
|
82
|
-
# Translate the supplied arguments into a
|
244
|
+
# Translate the supplied arguments into a +Criteria+ object.
|
245
|
+
#
|
246
|
+
# If the passed in args is a single +String+, then it will
|
247
|
+
# construct an id +Criteria+ from it.
|
248
|
+
#
|
249
|
+
# If the passed in args are a type and a hash, then it will construct
|
250
|
+
# the +Criteria+ with the proper selector, options, and type.
|
251
|
+
#
|
252
|
+
# Options:
|
253
|
+
#
|
254
|
+
# args: either a +String+ or a +Symbol+, +Hash combination.
|
255
|
+
#
|
256
|
+
# Example:
|
257
|
+
#
|
258
|
+
# <tt>Criteria.translate("4ab2bc4b8ad548971900005c")</tt>
|
259
|
+
#
|
260
|
+
# <tt>Criteria.translate(:all, :conditions => { :field => "value"}, :limit => 20)</tt>
|
261
|
+
#
|
262
|
+
# Returns a new +Criteria+ object.
|
83
263
|
def self.translate(*args)
|
84
264
|
type, params = args[0], args[1] || {}
|
85
265
|
return new(:first).id(type.to_s) if type.is_a?(String)
|
data/lib/mongoid/document.rb
CHANGED
@@ -16,7 +16,6 @@ module Mongoid #:nodoc:
|
|
16
16
|
|
17
17
|
class << self
|
18
18
|
|
19
|
-
# Create an association to a parent Document.
|
20
19
|
# Get an aggregate count for the supplied group of fields and the
|
21
20
|
# selector that is provided.
|
22
21
|
def aggregate(fields, params = {})
|
@@ -61,7 +60,7 @@ module Mongoid #:nodoc:
|
|
61
60
|
# Model.find(:first, :attribute => "value")
|
62
61
|
# Model.find(:all, :attribute => "value")
|
63
62
|
def find(*args)
|
64
|
-
Criteria.translate(*args).execute(
|
63
|
+
Criteria.translate(*args).execute(self)
|
65
64
|
end
|
66
65
|
|
67
66
|
# Find a single Document given the passed selector, which is a Hash of attributes that
|
data/mongoid.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongoid}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.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{2009-10-
|
12
|
+
s.date = %q{2009-10-10}
|
13
13
|
s.email = %q{durran@gmail.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.textile"
|
@@ -51,7 +51,7 @@ Gem::Specification.new do |s|
|
|
51
51
|
s.rdoc_options = ["--charset=UTF-8"]
|
52
52
|
s.require_paths = ["lib"]
|
53
53
|
s.rubygems_version = %q{1.3.5}
|
54
|
-
s.summary = %q{
|
54
|
+
s.summary = %q{ODM framework for MongoDB}
|
55
55
|
s.test_files = [
|
56
56
|
"spec/integration/mongoid/document_spec.rb",
|
57
57
|
"spec/spec_helper.rb",
|
@@ -39,8 +39,9 @@ describe Mongoid::Criteria do
|
|
39
39
|
it "calls find on the collection with the selector and options" do
|
40
40
|
criteria = Mongoid::Criteria.new(:first)
|
41
41
|
collection = mock
|
42
|
+
Person.expects(:collection).returns(collection)
|
42
43
|
collection.expects(:find_one).with(@criteria.selector, @criteria.options).returns({})
|
43
|
-
criteria.execute(
|
44
|
+
criteria.execute(Person).should be_a_kind_of(Person)
|
44
45
|
end
|
45
46
|
|
46
47
|
end
|
@@ -50,8 +51,9 @@ describe Mongoid::Criteria do
|
|
50
51
|
it "calls find on the collection with the selector and options" do
|
51
52
|
criteria = Mongoid::Criteria.new(:all)
|
52
53
|
collection = mock
|
54
|
+
Person.expects(:collection).returns(collection)
|
53
55
|
collection.expects(:find).with(@criteria.selector, @criteria.options).returns([])
|
54
|
-
criteria.execute(
|
56
|
+
criteria.execute(Person).should == []
|
55
57
|
end
|
56
58
|
|
57
59
|
end
|
@@ -137,7 +137,7 @@ describe Mongoid::Document do
|
|
137
137
|
|
138
138
|
it "delegates to criteria" do
|
139
139
|
Mongoid::Criteria.expects(:translate).with(@id.to_s).returns(@criteria)
|
140
|
-
@criteria.expects(:execute).with(
|
140
|
+
@criteria.expects(:execute).with(Person).returns(@attributes)
|
141
141
|
Person.find(@id.to_s)
|
142
142
|
end
|
143
143
|
|
@@ -147,7 +147,7 @@ describe Mongoid::Document do
|
|
147
147
|
|
148
148
|
it "delegates to criteria" do
|
149
149
|
Mongoid::Criteria.expects(:translate).with(:first, :conditions => { :test => "Test" }).returns(@criteria)
|
150
|
-
@criteria.expects(:execute).with(
|
150
|
+
@criteria.expects(:execute).with(Person).returns(@attributes)
|
151
151
|
Person.find(:first, :conditions => { :test => "Test" })
|
152
152
|
end
|
153
153
|
|
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.
|
4
|
+
version: 0.4.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: 2009-10-
|
12
|
+
date: 2009-10-10 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -119,7 +119,7 @@ rubyforge_project:
|
|
119
119
|
rubygems_version: 1.3.5
|
120
120
|
signing_key:
|
121
121
|
specification_version: 3
|
122
|
-
summary:
|
122
|
+
summary: ODM framework for MongoDB
|
123
123
|
test_files:
|
124
124
|
- spec/integration/mongoid/document_spec.rb
|
125
125
|
- spec/spec_helper.rb
|