jnunemaker-mongomapper 0.3.3 → 0.3.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/History +6 -0
- data/VERSION +1 -1
- data/lib/mongomapper.rb +5 -3
- data/lib/mongomapper/associations.rb +0 -12
- data/lib/mongomapper/associations/base.rb +28 -16
- data/lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb +2 -2
- data/lib/mongomapper/associations/belongs_to_proxy.rb +2 -2
- data/lib/mongomapper/associations/many_documents_as_proxy.rb +27 -0
- data/lib/mongomapper/document.rb +24 -7
- data/lib/mongomapper/embedded_document.rb +25 -14
- data/lib/mongomapper/serialization.rb +1 -1
- data/mongomapper.gemspec +5 -2
- data/test/functional/associations/test_many_documents_as_proxy.rb +253 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +36 -34
- data/test/functional/associations/test_many_proxy.rb +7 -7
- data/test/functional/test_associations.rb +9 -2
- data/test/functional/test_document.rb +12 -4
- data/test/models.rb +59 -2
- data/test/unit/serializers/test_json_serializer.rb +36 -4
- data/test/unit/test_association_base.rb +10 -2
- data/test/unit/test_document.rb +0 -8
- data/test/unit/test_embedded_document.rb +65 -0
- data/test/unit/test_key.rb +7 -0
- metadata +6 -4
data/History
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
0.3.4 8/28/2009
|
2
|
+
* BACKWORDS COMPATIBILITY BREAK: Timestamps are now optional. To use them add timestamps! to your model.
|
3
|
+
* BACKWORDS COMPATIBILITY BREAK: Associations keys are no longer created automatically when you use belongs_to and many. Too much was hidden from the developer. You now have to declare them like key :creator_id, String and such.
|
4
|
+
* to_json now includes dynamic keys and embedded stuff by default
|
5
|
+
* added polymorphic many with :as option (dcu)
|
6
|
+
|
1
7
|
0.3.3 8/16/2009
|
2
8
|
* BACKWORDS COMPATIBILITY BREAK: _id is now once again a string rather than an object id and will stay that way.
|
3
9
|
* Custom id's can now be used because of the change to string id's
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.4
|
data/lib/mongomapper.rb
CHANGED
@@ -25,6 +25,7 @@ require dir + 'associations/many_proxy'
|
|
25
25
|
require dir + 'associations/many_polymorphic_proxy'
|
26
26
|
require dir + 'associations/many_embedded_proxy'
|
27
27
|
require dir + 'associations/many_embedded_polymorphic_proxy'
|
28
|
+
require dir + 'associations/many_documents_as_proxy'
|
28
29
|
|
29
30
|
require dir + 'callbacks'
|
30
31
|
require dir + 'finder_options'
|
@@ -43,14 +44,15 @@ require dir + 'embedded_document'
|
|
43
44
|
require dir + 'document'
|
44
45
|
|
45
46
|
module MongoMapper
|
46
|
-
DocumentNotFound
|
47
|
-
|
47
|
+
DocumentNotFound = Class.new(StandardError)
|
48
|
+
|
49
|
+
DocumentNotValid = Class.new(StandardError) do
|
48
50
|
def initialize(document)
|
49
51
|
@document = document
|
50
52
|
super("Validation failed: #{@document.errors.full_messages.join(", ")}")
|
51
53
|
end
|
52
54
|
end
|
53
|
-
|
55
|
+
|
54
56
|
def self.connection
|
55
57
|
@@connection ||= XGen::Mongo::Driver::Mongo.new
|
56
58
|
end
|
@@ -20,7 +20,6 @@ module MongoMapper
|
|
20
20
|
association = Associations::Base.new(type, name, options)
|
21
21
|
associations[association.name] = association
|
22
22
|
define_association_methods(association)
|
23
|
-
define_association_keys(association)
|
24
23
|
define_dependent_callback(association)
|
25
24
|
association
|
26
25
|
end
|
@@ -36,17 +35,6 @@ module MongoMapper
|
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
|
-
def define_association_keys(association)
|
40
|
-
if association.belongs_to?
|
41
|
-
key(association.belongs_to_key_name, String)
|
42
|
-
key(association.type_key_name, String) if association.polymorphic?
|
43
|
-
end
|
44
|
-
|
45
|
-
if association.many? && association.polymorphic?
|
46
|
-
association.klass.send(:key, association.type_key_name, String)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
38
|
def define_dependent_callback(association)
|
51
39
|
if association.options[:dependent]
|
52
40
|
if association.many?
|
@@ -4,11 +4,9 @@ module MongoMapper
|
|
4
4
|
attr_reader :type, :name, :options
|
5
5
|
|
6
6
|
def initialize(type, name, options = {})
|
7
|
-
@options = options
|
8
|
-
@type = type
|
9
|
-
@name = name
|
7
|
+
@type, @name, @options = type, name, options
|
10
8
|
end
|
11
|
-
|
9
|
+
|
12
10
|
def class_name
|
13
11
|
@class_name ||= begin
|
14
12
|
if cn = options[:class_name]
|
@@ -20,35 +18,43 @@ module MongoMapper
|
|
20
18
|
end
|
21
19
|
end
|
22
20
|
end
|
23
|
-
|
21
|
+
|
24
22
|
def klass
|
25
23
|
@klass ||= class_name.constantize
|
26
24
|
end
|
27
|
-
|
25
|
+
|
28
26
|
def many?
|
29
27
|
@many_type ||= @type == :many
|
30
28
|
end
|
31
|
-
|
29
|
+
|
32
30
|
def belongs_to?
|
33
31
|
@belongs_to_type ||= @type == :belongs_to
|
34
32
|
end
|
35
|
-
|
33
|
+
|
36
34
|
def polymorphic?
|
37
35
|
!!@options[:polymorphic]
|
38
36
|
end
|
39
|
-
|
37
|
+
|
38
|
+
def as?
|
39
|
+
!!@options[:as]
|
40
|
+
end
|
41
|
+
|
40
42
|
def type_key_name
|
41
|
-
@type_key_name ||= many? ? '_type' : "#{
|
43
|
+
@type_key_name ||= many? ? '_type' : "#{as}_type"
|
44
|
+
end
|
45
|
+
|
46
|
+
def as
|
47
|
+
@options[:as] || self.name
|
42
48
|
end
|
43
|
-
|
44
|
-
def
|
45
|
-
"#{name}_id"
|
49
|
+
|
50
|
+
def foreign_key
|
51
|
+
@options[:foreign_key] || "#{name}_id"
|
46
52
|
end
|
47
|
-
|
53
|
+
|
48
54
|
def ivar
|
49
55
|
@ivar ||= "@_#{name}"
|
50
56
|
end
|
51
|
-
|
57
|
+
|
52
58
|
def embeddable?
|
53
59
|
many? && klass.embeddable?
|
54
60
|
end
|
@@ -59,7 +65,13 @@ module MongoMapper
|
|
59
65
|
if self.klass.embeddable?
|
60
66
|
polymorphic? ? ManyEmbeddedPolymorphicProxy : ManyEmbeddedProxy
|
61
67
|
else
|
62
|
-
polymorphic?
|
68
|
+
if polymorphic?
|
69
|
+
ManyPolymorphicProxy
|
70
|
+
elsif as?
|
71
|
+
ManyDocumentsAsProxy
|
72
|
+
else
|
73
|
+
ManyProxy
|
74
|
+
end
|
63
75
|
end
|
64
76
|
else
|
65
77
|
polymorphic? ? BelongsToPolymorphicProxy : BelongsToProxy
|
@@ -7,7 +7,7 @@ module MongoMapper
|
|
7
7
|
id, type = doc.id, doc.class.name
|
8
8
|
end
|
9
9
|
|
10
|
-
@owner.send("#{@association.
|
10
|
+
@owner.send("#{@association.foreign_key}=", id)
|
11
11
|
@owner.send("#{@association.type_key_name}=", type)
|
12
12
|
reset
|
13
13
|
end
|
@@ -20,7 +20,7 @@ module MongoMapper
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def proxy_id
|
23
|
-
@proxy_id ||= @owner.send(@association.
|
23
|
+
@proxy_id ||= @owner.send(@association.foreign_key)
|
24
24
|
end
|
25
25
|
|
26
26
|
def proxy_class
|
@@ -7,13 +7,13 @@ module MongoMapper
|
|
7
7
|
id = doc.id
|
8
8
|
end
|
9
9
|
|
10
|
-
@owner.send("#{@association.
|
10
|
+
@owner.send("#{@association.foreign_key}=", id)
|
11
11
|
reset
|
12
12
|
end
|
13
13
|
|
14
14
|
protected
|
15
15
|
def find_target
|
16
|
-
if association_id = @owner.send(@association.
|
16
|
+
if association_id = @owner.send(@association.foreign_key)
|
17
17
|
@association.klass.find_by_id(association_id)
|
18
18
|
end
|
19
19
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Associations
|
3
|
+
class ManyDocumentsAsProxy < ManyDocumentsProxy
|
4
|
+
protected
|
5
|
+
def scoped_conditions
|
6
|
+
{as_type_name => @owner.class.name, as_id_name => @owner.id}
|
7
|
+
end
|
8
|
+
|
9
|
+
def apply_scope(doc)
|
10
|
+
ensure_owner_saved
|
11
|
+
|
12
|
+
doc.send("#{as_type_name}=", @owner.class.name)
|
13
|
+
doc.send("#{as_id_name}=", @owner.id)
|
14
|
+
|
15
|
+
doc
|
16
|
+
end
|
17
|
+
|
18
|
+
def as_type_name
|
19
|
+
@as_type_name ||= @association.options[:as].to_s + "_type"
|
20
|
+
end
|
21
|
+
|
22
|
+
def as_id_name
|
23
|
+
@as_id_name ||= @association.options[:as].to_s + "_id"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/mongomapper/document.rb
CHANGED
@@ -11,9 +11,6 @@ module MongoMapper
|
|
11
11
|
include SaveWithValidation
|
12
12
|
include RailsCompatibility::Document
|
13
13
|
extend ClassMethods
|
14
|
-
|
15
|
-
key :created_at, Time
|
16
|
-
key :updated_at, Time
|
17
14
|
end
|
18
15
|
|
19
16
|
descendants << model
|
@@ -140,7 +137,14 @@ module MongoMapper
|
|
140
137
|
end
|
141
138
|
@collection
|
142
139
|
end
|
143
|
-
|
140
|
+
|
141
|
+
def timestamps!
|
142
|
+
key :created_at, Time
|
143
|
+
key :updated_at, Time
|
144
|
+
|
145
|
+
class_eval { before_save :update_timestamps }
|
146
|
+
end
|
147
|
+
|
144
148
|
def validates_uniqueness_of(*args)
|
145
149
|
add_validations(args, MongoMapper::Validations::ValidatesUniquenessOf)
|
146
150
|
end
|
@@ -181,7 +185,22 @@ module MongoMapper
|
|
181
185
|
|
182
186
|
def find_last(options)
|
183
187
|
options.merge!(:limit => 1)
|
184
|
-
|
188
|
+
options[:order] = invert_order_clause(options)
|
189
|
+
find_every(options)[0]
|
190
|
+
#find_every({:order => '$natural desc'}.merge(invert_order_clause(options)))[0]
|
191
|
+
end
|
192
|
+
|
193
|
+
def invert_order_clause(options)
|
194
|
+
return '$natural desc' unless options[:order]
|
195
|
+
options[:order].split(',').map do |order_segment|
|
196
|
+
if order_segment =~ /\sasc/i
|
197
|
+
order_segment.sub /\sasc/i, ' desc'
|
198
|
+
elsif order_segment =~ /\sdesc/i
|
199
|
+
order_segment.sub /\sdesc/i, ' asc'
|
200
|
+
else
|
201
|
+
"#{order_segment.strip} desc"
|
202
|
+
end
|
203
|
+
end.join(',')
|
185
204
|
end
|
186
205
|
|
187
206
|
def find_some(ids, options={})
|
@@ -295,7 +314,6 @@ module MongoMapper
|
|
295
314
|
end
|
296
315
|
|
297
316
|
def create
|
298
|
-
update_timestamps
|
299
317
|
assign_id
|
300
318
|
save_to_collection
|
301
319
|
end
|
@@ -307,7 +325,6 @@ module MongoMapper
|
|
307
325
|
end
|
308
326
|
|
309
327
|
def update
|
310
|
-
update_timestamps
|
311
328
|
save_to_collection
|
312
329
|
end
|
313
330
|
|
@@ -77,28 +77,39 @@ module MongoMapper
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def parent_model
|
80
|
-
|
81
|
-
|
80
|
+
(ancestors - [self,EmbeddedDocument]).find do |parent_class|
|
81
|
+
parent_class.ancestors.include?(EmbeddedDocument)
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
85
|
private
|
86
|
-
def
|
87
|
-
|
88
|
-
|
86
|
+
def accessors_module
|
87
|
+
if const_defined?('MongoMapperKeys') && constants.include?( 'MongoMapperKeys' )
|
88
|
+
const_get 'MongoMapperKeys'
|
89
|
+
else
|
90
|
+
const_set 'MongoMapperKeys', Module.new
|
89
91
|
end
|
92
|
+
end
|
90
93
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
+
def create_accessors_for(key)
|
95
|
+
accessors_module.module_eval <<-end_eval
|
96
|
+
def #{key.name}
|
97
|
+
read_attribute( :'#{key.name}' )
|
98
|
+
end
|
94
99
|
|
95
|
-
|
96
|
-
|
97
|
-
|
100
|
+
def #{key.name}_before_typecast
|
101
|
+
read_attribute_before_typecast(:'#{key.name}')
|
102
|
+
end
|
98
103
|
|
99
|
-
|
100
|
-
|
101
|
-
|
104
|
+
def #{key.name}=(value)
|
105
|
+
write_attribute(:'#{key.name}', value)
|
106
|
+
end
|
107
|
+
|
108
|
+
def #{key.name}?
|
109
|
+
read_attribute(:#{key.name}).present?
|
110
|
+
end
|
111
|
+
end_eval
|
112
|
+
include accessors_module
|
102
113
|
end
|
103
114
|
|
104
115
|
def create_indexes_for(key)
|
data/mongomapper.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongomapper}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["John Nunemaker"]
|
12
|
-
s.date = %q{2009-08-
|
12
|
+
s.date = %q{2009-08-28}
|
13
13
|
s.default_executable = %q{mmconsole}
|
14
14
|
s.email = %q{nunemaker@gmail.com}
|
15
15
|
s.executables = ["mmconsole"]
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
"lib/mongomapper/associations/base.rb",
|
31
31
|
"lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb",
|
32
32
|
"lib/mongomapper/associations/belongs_to_proxy.rb",
|
33
|
+
"lib/mongomapper/associations/many_documents_as_proxy.rb",
|
33
34
|
"lib/mongomapper/associations/many_documents_proxy.rb",
|
34
35
|
"lib/mongomapper/associations/many_embedded_polymorphic_proxy.rb",
|
35
36
|
"lib/mongomapper/associations/many_embedded_proxy.rb",
|
@@ -55,6 +56,7 @@ Gem::Specification.new do |s|
|
|
55
56
|
"test/NOTE_ON_TESTING",
|
56
57
|
"test/functional/associations/test_belongs_to_polymorphic_proxy.rb",
|
57
58
|
"test/functional/associations/test_belongs_to_proxy.rb",
|
59
|
+
"test/functional/associations/test_many_documents_as_proxy.rb",
|
58
60
|
"test/functional/associations/test_many_embedded_polymorphic_proxy.rb",
|
59
61
|
"test/functional/associations/test_many_embedded_proxy.rb",
|
60
62
|
"test/functional/associations/test_many_polymorphic_proxy.rb",
|
@@ -89,6 +91,7 @@ Gem::Specification.new do |s|
|
|
89
91
|
s.test_files = [
|
90
92
|
"test/functional/associations/test_belongs_to_polymorphic_proxy.rb",
|
91
93
|
"test/functional/associations/test_belongs_to_proxy.rb",
|
94
|
+
"test/functional/associations/test_many_documents_as_proxy.rb",
|
92
95
|
"test/functional/associations/test_many_embedded_polymorphic_proxy.rb",
|
93
96
|
"test/functional/associations/test_many_embedded_proxy.rb",
|
94
97
|
"test/functional/associations/test_many_polymorphic_proxy.rb",
|
@@ -0,0 +1,253 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class ManyDocumentsAsProxyTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
clear_all_collections
|
7
|
+
end
|
8
|
+
|
9
|
+
should "default reader to empty array" do
|
10
|
+
Post.new.comments.should == []
|
11
|
+
end
|
12
|
+
|
13
|
+
should "add type and id key to polymorphic class base" do
|
14
|
+
PostComment.keys.keys.should include('commentable_type')
|
15
|
+
PostComment.keys.keys.should include('commentable_id')
|
16
|
+
end
|
17
|
+
|
18
|
+
should "allow adding to association like it was an array" do
|
19
|
+
post = Post.new
|
20
|
+
post.comments << PostComment.new(:body => 'foo bar')
|
21
|
+
post.comments << PostComment.new(:body => 'baz')
|
22
|
+
post.comments.concat PostComment.new(:body => 'baz')
|
23
|
+
|
24
|
+
post.comments.size.should == 3
|
25
|
+
end
|
26
|
+
|
27
|
+
should "be able to replace the association" do
|
28
|
+
post = Post.new
|
29
|
+
|
30
|
+
lambda {
|
31
|
+
post.comments = [
|
32
|
+
PostComment.new(:body => 'foo'),
|
33
|
+
PostComment.new(:body => 'bar'),
|
34
|
+
PostComment.new(:body => 'baz')
|
35
|
+
]
|
36
|
+
}.should change { PostComment.count }.by(3)
|
37
|
+
|
38
|
+
from_db = Post.find(post.id)
|
39
|
+
from_db.comments.size.should == 3
|
40
|
+
from_db.comments[0].body.should == 'foo'
|
41
|
+
from_db.comments[1].body.should == 'bar'
|
42
|
+
from_db.comments[2].body.should == 'baz'
|
43
|
+
end
|
44
|
+
|
45
|
+
context "build" do
|
46
|
+
should "assign foreign key" do
|
47
|
+
post = Post.new
|
48
|
+
comment = post.comments.build
|
49
|
+
comment.commentable_id.should == post.id
|
50
|
+
end
|
51
|
+
|
52
|
+
should "assign _type" do
|
53
|
+
post = Post.new
|
54
|
+
comment = post.comments.build
|
55
|
+
comment.commentable_type.should == "Post"
|
56
|
+
end
|
57
|
+
|
58
|
+
should "allow assigning attributes" do
|
59
|
+
post = Post.new
|
60
|
+
comment = post.comments.build(:body => 'foo bar')
|
61
|
+
comment.body.should == 'foo bar'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "create" do
|
66
|
+
should "assign foreign key" do
|
67
|
+
post = Post.new
|
68
|
+
comment = post.comments.create
|
69
|
+
comment.commentable_id.should == post.id
|
70
|
+
end
|
71
|
+
|
72
|
+
should "assign _type" do
|
73
|
+
post = Post.new
|
74
|
+
comment = post.comments.create
|
75
|
+
comment.commentable_type.should == "Post"
|
76
|
+
end
|
77
|
+
|
78
|
+
should "save record" do
|
79
|
+
post = Post.new
|
80
|
+
lambda {
|
81
|
+
post.comments.create(:body => 'baz')
|
82
|
+
}.should change { PostComment.count }
|
83
|
+
end
|
84
|
+
|
85
|
+
should "allow passing attributes" do
|
86
|
+
post = Post.create
|
87
|
+
comment = post.comments.create(:body => 'foo bar')
|
88
|
+
comment.body.should == 'foo bar'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "count" do
|
93
|
+
should "work scoped to association" do
|
94
|
+
post = Post.create
|
95
|
+
3.times { post.comments.create(:body => 'foo bar') }
|
96
|
+
|
97
|
+
other_post = Post.create
|
98
|
+
2.times { other_post.comments.create(:body => 'baz') }
|
99
|
+
|
100
|
+
post.comments.count.should == 3
|
101
|
+
other_post.comments.count.should == 2
|
102
|
+
end
|
103
|
+
|
104
|
+
should "work with conditions" do
|
105
|
+
post = Post.create
|
106
|
+
post.comments.create(:body => 'foo bar')
|
107
|
+
post.comments.create(:body => 'baz')
|
108
|
+
post.comments.create(:body => 'foo bar')
|
109
|
+
|
110
|
+
post.comments.count(:body => 'foo bar').should == 2
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "Finding scoped to association" do
|
115
|
+
setup do
|
116
|
+
@post = Post.new
|
117
|
+
|
118
|
+
@comment1 = PostComment.create(:body => 'comment1')
|
119
|
+
@comment2 = PostComment.create(:body => 'comment2')
|
120
|
+
@comment3 = PostComment.create(:body => 'comment3')
|
121
|
+
@post.comments = [@comment1, @comment2]
|
122
|
+
@post.save
|
123
|
+
|
124
|
+
@post2 = Post.create(:body => "post #2")
|
125
|
+
@comment4 = PostComment.create(:body => 'comment4')
|
126
|
+
@comment5 = PostComment.create(:body => 'comment5')
|
127
|
+
@comment6 = PostComment.create(:body => 'comment6')
|
128
|
+
@post2.comments = [@comment4, @comment5, @comment6]
|
129
|
+
@post2.save
|
130
|
+
end
|
131
|
+
|
132
|
+
context "with :all" do
|
133
|
+
should "work" do
|
134
|
+
@post.comments.find(:all).should include(@comment1)
|
135
|
+
@post.comments.find(:all).should include(@comment2)
|
136
|
+
end
|
137
|
+
|
138
|
+
should "work with conditions" do
|
139
|
+
comments = @post.comments.find(:all, :conditions => {:body => 'comment1'})
|
140
|
+
comments.should == [@comment1]
|
141
|
+
end
|
142
|
+
|
143
|
+
should "work with order" do
|
144
|
+
comments = @post.comments.find(:all, :order => '$natural desc')
|
145
|
+
comments.should == [@comment2, @comment1]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "with #all" do
|
150
|
+
should "work" do
|
151
|
+
@post.comments.all.should == [@comment1, @comment2]
|
152
|
+
end
|
153
|
+
|
154
|
+
should "work with conditions" do
|
155
|
+
comments = @post.comments.all(:conditions => {:body => 'comment1'})
|
156
|
+
comments.should == [@comment1]
|
157
|
+
end
|
158
|
+
|
159
|
+
should "work with order" do
|
160
|
+
comments = @post.comments.all(:order => '$natural desc')
|
161
|
+
comments.should == [@comment2, @comment1]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context "with :first" do
|
166
|
+
should "work" do
|
167
|
+
lambda {@post.comments.find(:first)}.should_not raise_error
|
168
|
+
end
|
169
|
+
|
170
|
+
should "work with conditions" do
|
171
|
+
comment = @post.comments.find(:first, :conditions => {:body => 'comment2'})
|
172
|
+
comment.body.should == 'comment2'
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context "with #first" do
|
177
|
+
should "work" do
|
178
|
+
@post.comments.first.should == @comment1
|
179
|
+
end
|
180
|
+
|
181
|
+
should "work with conditions" do
|
182
|
+
comment = @post.comments.first(:conditions => {:body => 'comment2'})
|
183
|
+
comment.should == @comment2
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "with :last" do
|
188
|
+
should "work" do
|
189
|
+
@post.comments.find(:last, :order => 'created_at asc').should == @comment2
|
190
|
+
end
|
191
|
+
|
192
|
+
should "work with conditions" do
|
193
|
+
post = @post.comments.find(:last, :conditions => {:body => 'comment1'})
|
194
|
+
post.body.should == 'comment1'
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context "with #last" do
|
199
|
+
should "work" do
|
200
|
+
@post.comments.last.should == @comment2
|
201
|
+
end
|
202
|
+
|
203
|
+
should "work with conditions" do
|
204
|
+
comment = @post.comments.last(:conditions => {:body => 'comment1'})
|
205
|
+
comment.should == @comment1
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context "with one id" do
|
210
|
+
should "work for id in association" do
|
211
|
+
@post.comments.find(@comment2.id).should == @comment2
|
212
|
+
end
|
213
|
+
|
214
|
+
should "not work for id not in association" do
|
215
|
+
lambda {
|
216
|
+
@post.comments.find(@comment5.id)
|
217
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context "with multiple ids" do
|
222
|
+
should "work for ids in association" do
|
223
|
+
posts = @post.comments.find(@comment1.id, @comment2.id)
|
224
|
+
posts.should == [@comment1, @comment2]
|
225
|
+
end
|
226
|
+
|
227
|
+
should "not work for ids not in association" do
|
228
|
+
lambda {
|
229
|
+
@post.comments.find(@comment1.id, @comment2.id, @comment4.id)
|
230
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
context "with #paginate" do
|
235
|
+
setup do
|
236
|
+
@comments = @post2.comments.paginate(:per_page => 2, :page => 1, :order => 'created_at asc')
|
237
|
+
end
|
238
|
+
|
239
|
+
should "return total pages" do
|
240
|
+
@comments.total_pages.should == 2
|
241
|
+
end
|
242
|
+
|
243
|
+
should "return total entries" do
|
244
|
+
@comments.total_entries.should == 3
|
245
|
+
end
|
246
|
+
|
247
|
+
should "return the subject" do
|
248
|
+
@comments.should include(@comment4)
|
249
|
+
@comments.should include(@comment5)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|