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