danielharan-mongo_mapper 0.6.5
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/.gitignore +10 -0
- data/LICENSE +20 -0
- data/README.rdoc +53 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/bin/mmconsole +60 -0
- data/lib/mongo_mapper.rb +134 -0
- data/lib/mongo_mapper/associations.rb +183 -0
- data/lib/mongo_mapper/associations/base.rb +110 -0
- data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +34 -0
- data/lib/mongo_mapper/associations/belongs_to_proxy.rb +22 -0
- data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +25 -0
- data/lib/mongo_mapper/associations/many_documents_proxy.rb +127 -0
- data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +33 -0
- data/lib/mongo_mapper/associations/many_embedded_proxy.rb +53 -0
- data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +11 -0
- data/lib/mongo_mapper/associations/many_proxy.rb +6 -0
- data/lib/mongo_mapper/associations/proxy.rb +80 -0
- data/lib/mongo_mapper/callbacks.rb +109 -0
- data/lib/mongo_mapper/dirty.rb +136 -0
- data/lib/mongo_mapper/document.rb +481 -0
- data/lib/mongo_mapper/dynamic_finder.rb +35 -0
- data/lib/mongo_mapper/embedded_document.rb +386 -0
- data/lib/mongo_mapper/finder_options.rb +133 -0
- data/lib/mongo_mapper/key.rb +36 -0
- data/lib/mongo_mapper/observing.rb +50 -0
- data/lib/mongo_mapper/pagination.rb +53 -0
- data/lib/mongo_mapper/rails_compatibility/document.rb +15 -0
- data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +27 -0
- data/lib/mongo_mapper/serialization.rb +54 -0
- data/lib/mongo_mapper/serializers/json_serializer.rb +92 -0
- data/lib/mongo_mapper/support.rb +193 -0
- data/lib/mongo_mapper/validations.rb +41 -0
- data/mongo_mapper.gemspec +171 -0
- data/specs.watchr +32 -0
- data/test/NOTE_ON_TESTING +1 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +55 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +48 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +246 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +156 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +196 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +339 -0
- data/test/functional/associations/test_many_proxy.rb +384 -0
- data/test/functional/test_associations.rb +44 -0
- data/test/functional/test_binary.rb +18 -0
- data/test/functional/test_callbacks.rb +85 -0
- data/test/functional/test_dirty.rb +159 -0
- data/test/functional/test_document.rb +1180 -0
- data/test/functional/test_embedded_document.rb +125 -0
- data/test/functional/test_logger.rb +20 -0
- data/test/functional/test_pagination.rb +95 -0
- data/test/functional/test_rails_compatibility.rb +25 -0
- data/test/functional/test_string_id_compatibility.rb +72 -0
- data/test/functional/test_validations.rb +369 -0
- data/test/models.rb +271 -0
- data/test/support/custom_matchers.rb +55 -0
- data/test/support/timing.rb +16 -0
- data/test/test_helper.rb +27 -0
- data/test/unit/serializers/test_json_serializer.rb +189 -0
- data/test/unit/test_association_base.rb +166 -0
- data/test/unit/test_document.rb +204 -0
- data/test/unit/test_dynamic_finder.rb +125 -0
- data/test/unit/test_embedded_document.rb +718 -0
- data/test/unit/test_finder_options.rb +296 -0
- data/test/unit/test_key.rb +172 -0
- data/test/unit/test_mongo_mapper.rb +65 -0
- data/test/unit/test_observing.rb +101 -0
- data/test/unit/test_pagination.rb +113 -0
- data/test/unit/test_rails_compatibility.rb +49 -0
- data/test/unit/test_serializations.rb +52 -0
- data/test/unit/test_support.rb +342 -0
- data/test/unit/test_time_zones.rb +40 -0
- data/test/unit/test_validations.rb +503 -0
- metadata +233 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Validations
|
3
|
+
module Macros
|
4
|
+
def validates_uniqueness_of(*args)
|
5
|
+
add_validations(args, MongoMapper::Validations::ValidatesUniquenessOf)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class ValidatesUniquenessOf < Validatable::ValidationBase
|
10
|
+
option :scope, :case_sensitive
|
11
|
+
default :case_sensitive => true
|
12
|
+
|
13
|
+
def valid?(instance)
|
14
|
+
value = instance[attribute]
|
15
|
+
return true if allow_blank && value.blank?
|
16
|
+
base_conditions = case_sensitive ? {self.attribute => value} : {}
|
17
|
+
doc = instance.class.first(base_conditions.merge(scope_conditions(instance)).merge(where_conditions(instance)))
|
18
|
+
doc.nil? || instance._id == doc._id
|
19
|
+
end
|
20
|
+
|
21
|
+
def message(instance)
|
22
|
+
super || "has already been taken"
|
23
|
+
end
|
24
|
+
|
25
|
+
def scope_conditions(instance)
|
26
|
+
return {} unless scope
|
27
|
+
Array(scope).inject({}) do |conditions, key|
|
28
|
+
conditions.merge(key => instance[key])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def where_conditions(instance)
|
33
|
+
conditions = {}
|
34
|
+
unless case_sensitive
|
35
|
+
conditions.merge!({'$where' => "this.#{attribute}.toLowerCase() == '#{instance[attribute].downcase}'"})
|
36
|
+
end
|
37
|
+
conditions
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{danielharan-mongo_mapper}
|
8
|
+
s.version = "0.6.5"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["John Nunemaker"]
|
12
|
+
s.date = %q{2009-12-01}
|
13
|
+
s.default_executable = %q{mmconsole}
|
14
|
+
s.email = %q{chebuctonian@gmail.com}
|
15
|
+
s.executables = ["mmconsole"]
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"LICENSE",
|
18
|
+
"README.rdoc"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"bin/mmconsole",
|
27
|
+
"lib/mongo_mapper.rb",
|
28
|
+
"lib/mongo_mapper/associations.rb",
|
29
|
+
"lib/mongo_mapper/associations/base.rb",
|
30
|
+
"lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb",
|
31
|
+
"lib/mongo_mapper/associations/belongs_to_proxy.rb",
|
32
|
+
"lib/mongo_mapper/associations/many_documents_as_proxy.rb",
|
33
|
+
"lib/mongo_mapper/associations/many_documents_proxy.rb",
|
34
|
+
"lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb",
|
35
|
+
"lib/mongo_mapper/associations/many_embedded_proxy.rb",
|
36
|
+
"lib/mongo_mapper/associations/many_polymorphic_proxy.rb",
|
37
|
+
"lib/mongo_mapper/associations/many_proxy.rb",
|
38
|
+
"lib/mongo_mapper/associations/proxy.rb",
|
39
|
+
"lib/mongo_mapper/callbacks.rb",
|
40
|
+
"lib/mongo_mapper/dirty.rb",
|
41
|
+
"lib/mongo_mapper/document.rb",
|
42
|
+
"lib/mongo_mapper/dynamic_finder.rb",
|
43
|
+
"lib/mongo_mapper/embedded_document.rb",
|
44
|
+
"lib/mongo_mapper/finder_options.rb",
|
45
|
+
"lib/mongo_mapper/key.rb",
|
46
|
+
"lib/mongo_mapper/observing.rb",
|
47
|
+
"lib/mongo_mapper/pagination.rb",
|
48
|
+
"lib/mongo_mapper/rails_compatibility/document.rb",
|
49
|
+
"lib/mongo_mapper/rails_compatibility/embedded_document.rb",
|
50
|
+
"lib/mongo_mapper/serialization.rb",
|
51
|
+
"lib/mongo_mapper/serializers/json_serializer.rb",
|
52
|
+
"lib/mongo_mapper/support.rb",
|
53
|
+
"lib/mongo_mapper/validations.rb",
|
54
|
+
"mongo_mapper.gemspec",
|
55
|
+
"specs.watchr",
|
56
|
+
"test/NOTE_ON_TESTING",
|
57
|
+
"test/functional/associations/test_belongs_to_polymorphic_proxy.rb",
|
58
|
+
"test/functional/associations/test_belongs_to_proxy.rb",
|
59
|
+
"test/functional/associations/test_many_documents_as_proxy.rb",
|
60
|
+
"test/functional/associations/test_many_embedded_polymorphic_proxy.rb",
|
61
|
+
"test/functional/associations/test_many_embedded_proxy.rb",
|
62
|
+
"test/functional/associations/test_many_polymorphic_proxy.rb",
|
63
|
+
"test/functional/associations/test_many_proxy.rb",
|
64
|
+
"test/functional/test_associations.rb",
|
65
|
+
"test/functional/test_binary.rb",
|
66
|
+
"test/functional/test_callbacks.rb",
|
67
|
+
"test/functional/test_dirty.rb",
|
68
|
+
"test/functional/test_document.rb",
|
69
|
+
"test/functional/test_embedded_document.rb",
|
70
|
+
"test/functional/test_logger.rb",
|
71
|
+
"test/functional/test_pagination.rb",
|
72
|
+
"test/functional/test_rails_compatibility.rb",
|
73
|
+
"test/functional/test_string_id_compatibility.rb",
|
74
|
+
"test/functional/test_validations.rb",
|
75
|
+
"test/models.rb",
|
76
|
+
"test/support/custom_matchers.rb",
|
77
|
+
"test/support/timing.rb",
|
78
|
+
"test/test_helper.rb",
|
79
|
+
"test/unit/serializers/test_json_serializer.rb",
|
80
|
+
"test/unit/test_association_base.rb",
|
81
|
+
"test/unit/test_document.rb",
|
82
|
+
"test/unit/test_dynamic_finder.rb",
|
83
|
+
"test/unit/test_embedded_document.rb",
|
84
|
+
"test/unit/test_finder_options.rb",
|
85
|
+
"test/unit/test_key.rb",
|
86
|
+
"test/unit/test_mongo_mapper.rb",
|
87
|
+
"test/unit/test_observing.rb",
|
88
|
+
"test/unit/test_pagination.rb",
|
89
|
+
"test/unit/test_rails_compatibility.rb",
|
90
|
+
"test/unit/test_serializations.rb",
|
91
|
+
"test/unit/test_support.rb",
|
92
|
+
"test/unit/test_time_zones.rb",
|
93
|
+
"test/unit/test_validations.rb"
|
94
|
+
]
|
95
|
+
s.homepage = %q{http://github.com/jnunemaker/mongomapper}
|
96
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
97
|
+
s.require_paths = ["lib"]
|
98
|
+
s.rubygems_version = %q{1.3.5}
|
99
|
+
s.summary = %q{Awesome gem for modeling your domain and storing it in mongo}
|
100
|
+
s.test_files = [
|
101
|
+
"test/functional/associations/test_belongs_to_polymorphic_proxy.rb",
|
102
|
+
"test/functional/associations/test_belongs_to_proxy.rb",
|
103
|
+
"test/functional/associations/test_many_documents_as_proxy.rb",
|
104
|
+
"test/functional/associations/test_many_embedded_polymorphic_proxy.rb",
|
105
|
+
"test/functional/associations/test_many_embedded_proxy.rb",
|
106
|
+
"test/functional/associations/test_many_polymorphic_proxy.rb",
|
107
|
+
"test/functional/associations/test_many_proxy.rb",
|
108
|
+
"test/functional/test_associations.rb",
|
109
|
+
"test/functional/test_binary.rb",
|
110
|
+
"test/functional/test_callbacks.rb",
|
111
|
+
"test/functional/test_dirty.rb",
|
112
|
+
"test/functional/test_document.rb",
|
113
|
+
"test/functional/test_embedded_document.rb",
|
114
|
+
"test/functional/test_logger.rb",
|
115
|
+
"test/functional/test_pagination.rb",
|
116
|
+
"test/functional/test_rails_compatibility.rb",
|
117
|
+
"test/functional/test_string_id_compatibility.rb",
|
118
|
+
"test/functional/test_validations.rb",
|
119
|
+
"test/models.rb",
|
120
|
+
"test/support/custom_matchers.rb",
|
121
|
+
"test/support/timing.rb",
|
122
|
+
"test/test_helper.rb",
|
123
|
+
"test/unit/serializers/test_json_serializer.rb",
|
124
|
+
"test/unit/test_association_base.rb",
|
125
|
+
"test/unit/test_document.rb",
|
126
|
+
"test/unit/test_dynamic_finder.rb",
|
127
|
+
"test/unit/test_embedded_document.rb",
|
128
|
+
"test/unit/test_finder_options.rb",
|
129
|
+
"test/unit/test_key.rb",
|
130
|
+
"test/unit/test_mongo_mapper.rb",
|
131
|
+
"test/unit/test_observing.rb",
|
132
|
+
"test/unit/test_pagination.rb",
|
133
|
+
"test/unit/test_rails_compatibility.rb",
|
134
|
+
"test/unit/test_serializations.rb",
|
135
|
+
"test/unit/test_support.rb",
|
136
|
+
"test/unit/test_time_zones.rb",
|
137
|
+
"test/unit/test_validations.rb"
|
138
|
+
]
|
139
|
+
|
140
|
+
if s.respond_to? :specification_version then
|
141
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
142
|
+
s.specification_version = 3
|
143
|
+
|
144
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
145
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3"])
|
146
|
+
s.add_runtime_dependency(%q<mongo>, ["= 0.18"])
|
147
|
+
s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.8.1"])
|
148
|
+
s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
149
|
+
s.add_development_dependency(%q<shoulda>, ["= 2.10.2"])
|
150
|
+
s.add_development_dependency(%q<timecop>, ["= 0.3.1"])
|
151
|
+
s.add_development_dependency(%q<mocha>, ["= 0.9.8"])
|
152
|
+
else
|
153
|
+
s.add_dependency(%q<activesupport>, [">= 2.3"])
|
154
|
+
s.add_dependency(%q<mongo>, ["= 0.18"])
|
155
|
+
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.1"])
|
156
|
+
s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
157
|
+
s.add_dependency(%q<shoulda>, ["= 2.10.2"])
|
158
|
+
s.add_dependency(%q<timecop>, ["= 0.3.1"])
|
159
|
+
s.add_dependency(%q<mocha>, ["= 0.9.8"])
|
160
|
+
end
|
161
|
+
else
|
162
|
+
s.add_dependency(%q<activesupport>, [">= 2.3"])
|
163
|
+
s.add_dependency(%q<mongo>, ["= 0.18"])
|
164
|
+
s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.1"])
|
165
|
+
s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
|
166
|
+
s.add_dependency(%q<shoulda>, ["= 2.10.2"])
|
167
|
+
s.add_dependency(%q<timecop>, ["= 0.3.1"])
|
168
|
+
s.add_dependency(%q<mocha>, ["= 0.9.8"])
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
data/specs.watchr
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
def run(cmd)
|
2
|
+
puts(cmd)
|
3
|
+
system(cmd)
|
4
|
+
end
|
5
|
+
|
6
|
+
def run_test_file(file)
|
7
|
+
run %Q(ruby -I"lib:test" -rubygems #{file})
|
8
|
+
end
|
9
|
+
|
10
|
+
def run_all_tests
|
11
|
+
run "rake test"
|
12
|
+
end
|
13
|
+
|
14
|
+
def related_test_files(path)
|
15
|
+
Dir['test/**/*.rb'].select { |file| file =~ /test_#{File.basename(path)}/ }
|
16
|
+
end
|
17
|
+
|
18
|
+
watch('test/test_helper\.rb') { run_all_tests }
|
19
|
+
watch('test/.*/test_.*\.rb') { |m| run_test_file(m[0]) }
|
20
|
+
watch('lib/.*') do |m|
|
21
|
+
related_test_files(m[0]).each { |file| run_test_file(file) }
|
22
|
+
end
|
23
|
+
|
24
|
+
# Ctrl-\
|
25
|
+
Signal.trap('QUIT') do
|
26
|
+
puts " --- Running all tests ---\n\n"
|
27
|
+
run_all_tests
|
28
|
+
end
|
29
|
+
|
30
|
+
# Ctrl-C
|
31
|
+
Signal.trap('INT') { abort("\n") }
|
32
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
I am doing my best to keep unit and functional tests separate. As I see them, functional tests hit the database and should never care about internals. Unit tests do not hit the database.
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Status.collection.remove
|
7
|
+
Project.collection.remove
|
8
|
+
end
|
9
|
+
|
10
|
+
should "default to nil" do
|
11
|
+
status = Status.new
|
12
|
+
status.target.nil?.should be_true
|
13
|
+
status.target.inspect.should == "nil"
|
14
|
+
end
|
15
|
+
|
16
|
+
should "be able to replace the association" do
|
17
|
+
status = Status.new(:name => 'Foo!')
|
18
|
+
project = Project.new(:name => "mongomapper")
|
19
|
+
status.target = project
|
20
|
+
status.save.should be_true
|
21
|
+
|
22
|
+
status = status.reload
|
23
|
+
status.target.nil?.should be_false
|
24
|
+
status.target_id.should == project._id
|
25
|
+
status.target_type.should == "Project"
|
26
|
+
status.target.name.should == "mongomapper"
|
27
|
+
end
|
28
|
+
|
29
|
+
should "unset the association" do
|
30
|
+
status = Status.new(:name => 'Foo!')
|
31
|
+
project = Project.new(:name => "mongomapper")
|
32
|
+
status.target = project
|
33
|
+
status.save.should be_true
|
34
|
+
|
35
|
+
status = status.reload
|
36
|
+
status.target = nil
|
37
|
+
status.target_type.nil?.should be_true
|
38
|
+
status.target_id.nil?.should be_true
|
39
|
+
status.target.nil?.should be_true
|
40
|
+
end
|
41
|
+
|
42
|
+
context "association id set but document not found" do
|
43
|
+
setup do
|
44
|
+
@status = Status.new(:name => 'Foo!')
|
45
|
+
project = Project.new(:name => "mongomapper")
|
46
|
+
@status.target = project
|
47
|
+
@status.save.should be_true
|
48
|
+
project.destroy
|
49
|
+
end
|
50
|
+
|
51
|
+
should "return nil instead of raising error" do
|
52
|
+
@status.target.nil?.should be_true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class BelongsToProxyTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@post_class = Class.new do
|
7
|
+
include MongoMapper::Document
|
8
|
+
end
|
9
|
+
|
10
|
+
@comment_class = Class.new do
|
11
|
+
include MongoMapper::Document
|
12
|
+
key :post_id, String
|
13
|
+
end
|
14
|
+
@comment_class.belongs_to :post, :class => @post_class
|
15
|
+
|
16
|
+
@post_class.collection.remove
|
17
|
+
@comment_class.collection.remove
|
18
|
+
end
|
19
|
+
|
20
|
+
should "default to nil" do
|
21
|
+
@comment_class.new.post.nil?.should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
should "be able to replace the association" do
|
25
|
+
post = @post_class.new(:name => 'mongomapper')
|
26
|
+
comment = @comment_class.new(:name => 'Foo!', :post => post)
|
27
|
+
comment.save.should be_true
|
28
|
+
|
29
|
+
comment = comment.reload
|
30
|
+
comment.post.should == post
|
31
|
+
comment.post.nil?.should be_false
|
32
|
+
end
|
33
|
+
|
34
|
+
should "unset the association" do
|
35
|
+
post = @post_class.new(:name => 'mongomapper')
|
36
|
+
comment = @comment_class.new(:name => 'Foo!', :post => post)
|
37
|
+
comment.save.should be_true
|
38
|
+
|
39
|
+
comment = comment.reload
|
40
|
+
comment.post = nil
|
41
|
+
comment.post.nil?.should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
should "return nil if id set but document not found" do
|
45
|
+
id = Mongo::ObjectID.new
|
46
|
+
@comment_class.new(:name => 'Foo', :post_id => id).post.nil?.should be_true
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class ManyDocumentsAsProxyTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Post.collection.remove
|
7
|
+
PostComment.collection.remove
|
8
|
+
end
|
9
|
+
|
10
|
+
should "default reader to empty array" do
|
11
|
+
Post.new.comments.should == []
|
12
|
+
end
|
13
|
+
|
14
|
+
should "add type and id key to polymorphic class base" do
|
15
|
+
PostComment.keys.keys.should include('commentable_type')
|
16
|
+
PostComment.keys.keys.should include('commentable_id')
|
17
|
+
end
|
18
|
+
|
19
|
+
should "allow adding to association like it was an array" do
|
20
|
+
post = Post.new
|
21
|
+
post.comments << PostComment.new(:body => 'foo bar')
|
22
|
+
post.comments << PostComment.new(:body => 'baz')
|
23
|
+
post.comments.concat PostComment.new(:body => 'baz')
|
24
|
+
|
25
|
+
post.comments.size.should == 3
|
26
|
+
end
|
27
|
+
|
28
|
+
should "be able to replace the association" do
|
29
|
+
post = Post.new
|
30
|
+
|
31
|
+
lambda {
|
32
|
+
post.comments = [
|
33
|
+
PostComment.new(:body => 'foo'),
|
34
|
+
PostComment.new(:body => 'bar'),
|
35
|
+
PostComment.new(:body => 'baz')
|
36
|
+
]
|
37
|
+
}.should change { PostComment.count }.by(3)
|
38
|
+
|
39
|
+
post = post.reload
|
40
|
+
post.comments.size.should == 3
|
41
|
+
bodies = post.comments.collect(&:body)
|
42
|
+
bodies.should include('foo')
|
43
|
+
bodies.should include('bar')
|
44
|
+
bodies.should include('baz')
|
45
|
+
end
|
46
|
+
|
47
|
+
context "build" do
|
48
|
+
should "assign foreign key" do
|
49
|
+
post = Post.new
|
50
|
+
comment = post.comments.build
|
51
|
+
comment.commentable_id.should == post._id
|
52
|
+
end
|
53
|
+
|
54
|
+
should "assign _type" do
|
55
|
+
post = Post.new
|
56
|
+
comment = post.comments.build
|
57
|
+
comment.commentable_type.should == "Post"
|
58
|
+
end
|
59
|
+
|
60
|
+
should "allow assigning attributes" do
|
61
|
+
post = Post.new
|
62
|
+
comment = post.comments.build(:body => 'foo bar')
|
63
|
+
comment.body.should == 'foo bar'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "create" do
|
68
|
+
should "assign foreign key" do
|
69
|
+
post = Post.new
|
70
|
+
comment = post.comments.create
|
71
|
+
comment.commentable_id.should == post._id
|
72
|
+
end
|
73
|
+
|
74
|
+
should "assign _type" do
|
75
|
+
post = Post.new
|
76
|
+
comment = post.comments.create
|
77
|
+
comment.commentable_type.should == "Post"
|
78
|
+
end
|
79
|
+
|
80
|
+
should "save record" do
|
81
|
+
post = Post.new
|
82
|
+
lambda {
|
83
|
+
post.comments.create(:body => 'baz')
|
84
|
+
}.should change { PostComment.count }
|
85
|
+
end
|
86
|
+
|
87
|
+
should "allow passing attributes" do
|
88
|
+
post = Post.create
|
89
|
+
comment = post.comments.create(:body => 'foo bar')
|
90
|
+
comment.body.should == 'foo bar'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "count" do
|
95
|
+
should "work scoped to association" do
|
96
|
+
post = Post.create
|
97
|
+
3.times { post.comments.create(:body => 'foo bar') }
|
98
|
+
|
99
|
+
other_post = Post.create
|
100
|
+
2.times { other_post.comments.create(:body => 'baz') }
|
101
|
+
|
102
|
+
post.comments.count.should == 3
|
103
|
+
other_post.comments.count.should == 2
|
104
|
+
end
|
105
|
+
|
106
|
+
should "work with conditions" do
|
107
|
+
post = Post.create
|
108
|
+
post.comments.create(:body => 'foo bar')
|
109
|
+
post.comments.create(:body => 'baz')
|
110
|
+
post.comments.create(:body => 'foo bar')
|
111
|
+
|
112
|
+
post.comments.count(:body => 'foo bar').should == 2
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "Finding scoped to association" do
|
117
|
+
setup do
|
118
|
+
@post = Post.new
|
119
|
+
|
120
|
+
@comment1 = PostComment.create(:body => 'comment1', :name => 'John')
|
121
|
+
@comment2 = PostComment.create(:body => 'comment2', :name => 'Steve')
|
122
|
+
@comment3 = PostComment.create(:body => 'comment3', :name => 'John')
|
123
|
+
@post.comments = [@comment1, @comment2]
|
124
|
+
@post.save
|
125
|
+
|
126
|
+
@post2 = Post.create(:body => "post #2")
|
127
|
+
@comment4 = PostComment.create(:body => 'comment1', :name => 'Chas')
|
128
|
+
@comment5 = PostComment.create(:body => 'comment2', :name => 'Dan')
|
129
|
+
@comment6 = PostComment.create(:body => 'comment3', :name => 'Ed')
|
130
|
+
@post2.comments = [@comment4, @comment5, @comment6]
|
131
|
+
@post2.save
|
132
|
+
end
|
133
|
+
|
134
|
+
context "with :all" do
|
135
|
+
should "work" do
|
136
|
+
@post.comments.find(:all).should include(@comment1)
|
137
|
+
@post.comments.find(:all).should include(@comment2)
|
138
|
+
end
|
139
|
+
|
140
|
+
should "work with conditions" do
|
141
|
+
comments = @post.comments.find(:all, :body => 'comment1')
|
142
|
+
comments.should == [@comment1]
|
143
|
+
end
|
144
|
+
|
145
|
+
should "work with order" do
|
146
|
+
comments = @post.comments.find(:all, :order => 'body desc')
|
147
|
+
comments.should == [@comment2, @comment1]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "with #all" do
|
152
|
+
should "work" do
|
153
|
+
@post.comments.all.should include(@comment1)
|
154
|
+
@post.comments.all.should include(@comment2)
|
155
|
+
end
|
156
|
+
|
157
|
+
should "work with conditions" do
|
158
|
+
comments = @post.comments.all(:body => 'comment1')
|
159
|
+
comments.should == [@comment1]
|
160
|
+
end
|
161
|
+
|
162
|
+
should "work with order" do
|
163
|
+
comments = @post.comments.all(:order => 'body desc')
|
164
|
+
comments.should == [@comment2, @comment1]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "with one id" do
|
169
|
+
should "work for id in association" do
|
170
|
+
@post.comments.find(@comment2._id).should == @comment2
|
171
|
+
end
|
172
|
+
|
173
|
+
should "not work for id not in association" do
|
174
|
+
lambda {
|
175
|
+
@post.comments.find!(@comment5._id)
|
176
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context "with multiple ids" do
|
181
|
+
should "work for ids in association" do
|
182
|
+
posts = @post.comments.find!(@comment1._id, @comment2._id)
|
183
|
+
posts.should == [@comment1, @comment2]
|
184
|
+
end
|
185
|
+
|
186
|
+
should "not work for ids not in association" do
|
187
|
+
lambda {
|
188
|
+
@post.comments.find!(@comment1._id, @comment2._id, @comment4._id)
|
189
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "dynamic finders" do
|
194
|
+
should "work with single key" do
|
195
|
+
@post.comments.find_by_body('comment1').should == @comment1
|
196
|
+
@post2.comments.find_by_body('comment1').should == @comment4
|
197
|
+
end
|
198
|
+
|
199
|
+
should "work with multiple keys" do
|
200
|
+
@post.comments.find_by_body_and_name('comment1', 'John').should == @comment1
|
201
|
+
@post.comments.find_by_body_and_name('comment1', 'Frank').should be_nil
|
202
|
+
end
|
203
|
+
|
204
|
+
should "raise error when using !" do
|
205
|
+
lambda {
|
206
|
+
@post.comments.find_by_body!('asdf')
|
207
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
208
|
+
end
|
209
|
+
|
210
|
+
context "find_or_create_by" do
|
211
|
+
should "not create document if found" do
|
212
|
+
lambda {
|
213
|
+
comment = @post.comments.find_or_create_by_name('Steve')
|
214
|
+
comment.commentable.should == @post
|
215
|
+
comment.should == @comment2
|
216
|
+
}.should_not change { PostComment.count }
|
217
|
+
end
|
218
|
+
|
219
|
+
should "create document if not found" do
|
220
|
+
lambda {
|
221
|
+
@post.comments.find_or_create_by_name('Chas')
|
222
|
+
}.should change { PostComment.count }.by(1)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
context "with #paginate" do
|
228
|
+
setup do
|
229
|
+
@comments = @post2.comments.paginate(:per_page => 2, :page => 1, :order => 'name')
|
230
|
+
end
|
231
|
+
|
232
|
+
should "return total pages" do
|
233
|
+
@comments.total_pages.should == 2
|
234
|
+
end
|
235
|
+
|
236
|
+
should "return total entries" do
|
237
|
+
@comments.total_entries.should == 3
|
238
|
+
end
|
239
|
+
|
240
|
+
should "return the subject" do
|
241
|
+
@comments.should include(@comment4)
|
242
|
+
@comments.should include(@comment5)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|