fcoury-mongomapper 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/History +3 -1
- data/README.rdoc +5 -3
- data/VERSION +1 -1
- data/bin/mmconsole +56 -0
- data/lib/mongomapper/associations/polymorphic_has_many_embedded_proxy.rb +10 -1
- data/lib/mongomapper/embedded_document.rb +16 -5
- data/mongomapper.gemspec +6 -2
- data/test/test_associations.rb +164 -48
- metadata +6 -5
data/.gitignore
CHANGED
data/History
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
0.2.1(working)
|
2
2
|
* 1 major addition
|
3
|
-
* Added Document#paginate which works just like find but adds pagination
|
3
|
+
* Added Document#paginate which works just like find but adds pagination (dcu did basics and I pimped)
|
4
|
+
* Added a basic console for playing around with MongoMapper (dcu)
|
5
|
+
* Embedded associations can now be deeply nested (Keith Hanson)
|
4
6
|
|
5
7
|
0.2.0 7/7/2009
|
6
8
|
* 2 major additions (observers, associations), several minor additions, and a few bug fixes
|
data/README.rdoc
CHANGED
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
Awesome gem for modeling your domain and storing it in mongo.
|
4
4
|
|
5
|
-
|
5
|
+
Releases are tagged on github and also released as gems on github and rubyforge. Master is pushed to whenever I add a patch or a new feature. To build from master, you can clone the code, generate the updated gemspec, build the gem and install.
|
6
6
|
|
7
|
-
|
7
|
+
* rake gemspec
|
8
|
+
* gem build mongomapper.gemspec
|
9
|
+
* gem install the gem that was built
|
8
10
|
|
9
11
|
== Note on Patches/Pull Requests
|
10
12
|
|
11
13
|
* Fork the project.
|
12
14
|
* Make your feature addition or bug fix.
|
13
15
|
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
14
|
-
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
16
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself in another branch so I can ignore when I pull)
|
15
17
|
* Send me a pull request. Bonus points for topic branches.
|
16
18
|
|
17
19
|
== Dependencies
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/bin/mmconsole
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.dirname(__FILE__)+"/../lib"
|
3
|
+
|
4
|
+
require 'mongomapper'
|
5
|
+
require 'irb'
|
6
|
+
|
7
|
+
IRB.setup(nil)
|
8
|
+
irb = IRB::Irb.new
|
9
|
+
|
10
|
+
IRB.conf[:MAIN_CONTEXT] = irb.context
|
11
|
+
|
12
|
+
irb.context.evaluate("require 'irb/completion'", 0)
|
13
|
+
irb.context.evaluate(%@
|
14
|
+
include XGen::Mongo::Driver
|
15
|
+
include MongoMapper
|
16
|
+
|
17
|
+
MongoMapper.database = "mmtest"
|
18
|
+
$db = MongoMapper.database
|
19
|
+
|
20
|
+
@, 0)
|
21
|
+
|
22
|
+
puts %@
|
23
|
+
Welcome to the MongoMapper Console!
|
24
|
+
|
25
|
+
Example 1:
|
26
|
+
things = $db.collection("things")
|
27
|
+
things.insert("name" => "Raw Thing")
|
28
|
+
things.insert("name" => "Another Thing", "date" => Time.now)
|
29
|
+
|
30
|
+
cursor = things.find("name" => "Raw Thing")
|
31
|
+
puts cursor.next_object.inspect
|
32
|
+
|
33
|
+
Example 2:
|
34
|
+
class Thing
|
35
|
+
include MongoMapper::Document
|
36
|
+
key :name, String, :required => true
|
37
|
+
key :date, Time
|
38
|
+
end
|
39
|
+
|
40
|
+
thing = Thing.new
|
41
|
+
thing.name = "My thing"
|
42
|
+
thing.date = Time.now
|
43
|
+
thing.save
|
44
|
+
|
45
|
+
all_things = Thing.all
|
46
|
+
puts all_things.map { |object| object.name }.inspect
|
47
|
+
|
48
|
+
@
|
49
|
+
|
50
|
+
trap("SIGINT") do
|
51
|
+
irb.signal_handle
|
52
|
+
end
|
53
|
+
catch(:IRB_EXIT) do
|
54
|
+
irb.eval_input
|
55
|
+
end
|
56
|
+
|
@@ -22,7 +22,16 @@ module MongoMapper
|
|
22
22
|
(@_values || []).map do |e|
|
23
23
|
ref_type = "#{@association.name}_type"
|
24
24
|
class_name = e[ref_type]
|
25
|
-
|
25
|
+
if class_name
|
26
|
+
current = Kernel
|
27
|
+
parts = class_name.split("::")
|
28
|
+
parts.each do |p|
|
29
|
+
current = current.const_get(p)
|
30
|
+
end
|
31
|
+
klass = current
|
32
|
+
else
|
33
|
+
@association.klass
|
34
|
+
end
|
26
35
|
klass.new(e)
|
27
36
|
end
|
28
37
|
end
|
@@ -214,14 +214,25 @@ module MongoMapper
|
|
214
214
|
end
|
215
215
|
|
216
216
|
def embedded_association_attributes
|
217
|
-
|
217
|
+
embedded_attributes = HashWithIndifferentAccess.new
|
218
218
|
self.class.associations.each_pair do |name, association|
|
219
|
-
|
220
|
-
|
221
|
-
|
219
|
+
|
220
|
+
if association.type == :many && association.klass.embeddable?
|
221
|
+
if documents = instance_variable_get(association.ivar)
|
222
|
+
embedded_attributes[name] = documents.collect do |item|
|
223
|
+
attributes_hash = item.attributes
|
224
|
+
|
225
|
+
item.send(:embedded_association_attributes).each_pair do |association_name, association_value|
|
226
|
+
attributes_hash[association_name] = association_value
|
227
|
+
end
|
228
|
+
|
229
|
+
attributes_hash
|
230
|
+
end
|
231
|
+
end
|
222
232
|
end
|
223
233
|
end
|
224
|
-
|
234
|
+
|
235
|
+
embedded_attributes
|
225
236
|
end
|
226
237
|
|
227
238
|
def initialize_associations(attrs={})
|
data/mongomapper.gemspec
CHANGED
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{mongomapper}
|
5
|
-
s.version = "0.3.
|
5
|
+
s.version = "0.3.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["John Nunemaker"]
|
9
9
|
s.date = %q{2009-07-19}
|
10
|
+
s.default_executable = %q{mmconsole}
|
10
11
|
s.email = %q{nunemaker@gmail.com}
|
12
|
+
s.executables = ["mmconsole"]
|
11
13
|
s.extra_rdoc_files = [
|
12
14
|
"LICENSE",
|
13
15
|
"README.rdoc"
|
@@ -19,6 +21,7 @@ Gem::Specification.new do |s|
|
|
19
21
|
"README.rdoc",
|
20
22
|
"Rakefile",
|
21
23
|
"VERSION",
|
24
|
+
"bin/mmconsole",
|
22
25
|
"lib/mongomapper.rb",
|
23
26
|
"lib/mongomapper/associations.rb",
|
24
27
|
"lib/mongomapper/associations/array_proxy.rb",
|
@@ -57,11 +60,12 @@ Gem::Specification.new do |s|
|
|
57
60
|
"test/test_serializations.rb",
|
58
61
|
"test/test_validations.rb"
|
59
62
|
]
|
63
|
+
s.has_rdoc = true
|
60
64
|
s.homepage = %q{http://github.com/jnunemaker/mongomapper}
|
61
65
|
s.rdoc_options = ["--charset=UTF-8"]
|
62
66
|
s.require_paths = ["lib"]
|
63
67
|
s.rubyforge_project = %q{mongomapper}
|
64
|
-
s.rubygems_version = %q{1.3.
|
68
|
+
s.rubygems_version = %q{1.3.2}
|
65
69
|
s.summary = %q{Awesome gem for modeling your domain and storing it in mongo}
|
66
70
|
s.test_files = [
|
67
71
|
"test/serializers/test_json_serializer.rb",
|
data/test/test_associations.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
|
2
|
+
require 'ruby-debug'
|
3
3
|
class Address
|
4
4
|
include MongoMapper::EmbeddedDocument
|
5
5
|
|
@@ -31,6 +31,68 @@ class Person
|
|
31
31
|
include MongoMapper::EmbeddedDocument
|
32
32
|
key :name, String
|
33
33
|
key :child, Person
|
34
|
+
|
35
|
+
many :pets
|
36
|
+
end
|
37
|
+
|
38
|
+
class Pet
|
39
|
+
include MongoMapper::EmbeddedDocument
|
40
|
+
|
41
|
+
key :name, String
|
42
|
+
key :species, String
|
43
|
+
end
|
44
|
+
|
45
|
+
class Media
|
46
|
+
include MongoMapper::EmbeddedDocument
|
47
|
+
key :file, String
|
48
|
+
end
|
49
|
+
|
50
|
+
class Video < Media
|
51
|
+
key :length, Integer
|
52
|
+
end
|
53
|
+
|
54
|
+
class Image < Media
|
55
|
+
key :width, Integer
|
56
|
+
key :height, Integer
|
57
|
+
end
|
58
|
+
|
59
|
+
class Music < Media
|
60
|
+
key :bitrate, String
|
61
|
+
end
|
62
|
+
|
63
|
+
class Catalog
|
64
|
+
include MongoMapper::Document
|
65
|
+
|
66
|
+
many :medias, :polymorphic => true
|
67
|
+
end
|
68
|
+
|
69
|
+
module TrModels
|
70
|
+
class Transport
|
71
|
+
include MongoMapper::EmbeddedDocument
|
72
|
+
key :license_plate, String
|
73
|
+
end
|
74
|
+
|
75
|
+
class Car < TrModels::Transport
|
76
|
+
include MongoMapper::EmbeddedDocument
|
77
|
+
key :model, String
|
78
|
+
key :year, Integer
|
79
|
+
end
|
80
|
+
|
81
|
+
class Bus < TrModels::Transport
|
82
|
+
include MongoMapper::EmbeddedDocument
|
83
|
+
key :max_passengers, Integer
|
84
|
+
end
|
85
|
+
|
86
|
+
class Ambulance < TrModels::Transport
|
87
|
+
include MongoMapper::EmbeddedDocument
|
88
|
+
key :icu, Boolean
|
89
|
+
end
|
90
|
+
|
91
|
+
class Fleet
|
92
|
+
include MongoMapper::Document
|
93
|
+
many :transports, :polymorphic => true, :class_name => "TrModels::Transport"
|
94
|
+
key :name, String
|
95
|
+
end
|
34
96
|
end
|
35
97
|
|
36
98
|
class Media
|
@@ -57,12 +119,85 @@ class Catalog
|
|
57
119
|
many :medias, :polymorphic => true
|
58
120
|
end
|
59
121
|
|
122
|
+
module TrModels
|
123
|
+
class Transport
|
124
|
+
include MongoMapper::EmbeddedDocument
|
125
|
+
key :license_plate, String
|
126
|
+
end
|
127
|
+
|
128
|
+
class Car < TrModels::Transport
|
129
|
+
include MongoMapper::EmbeddedDocument
|
130
|
+
key :model, String
|
131
|
+
key :year, Integer
|
132
|
+
end
|
133
|
+
|
134
|
+
class Bus < TrModels::Transport
|
135
|
+
include MongoMapper::EmbeddedDocument
|
136
|
+
key :max_passengers, Integer
|
137
|
+
end
|
138
|
+
|
139
|
+
class Ambulance < TrModels::Transport
|
140
|
+
include MongoMapper::EmbeddedDocument
|
141
|
+
key :icu, Boolean
|
142
|
+
end
|
143
|
+
|
144
|
+
class Fleet
|
145
|
+
include MongoMapper::Document
|
146
|
+
many :transports, :polymorphic => true, :class_name => "TrModels::Transport"
|
147
|
+
key :name, String
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
60
151
|
class AssociationsTest < Test::Unit::TestCase
|
61
152
|
def setup
|
62
153
|
Project.collection.clear
|
63
154
|
Status.collection.clear
|
64
155
|
end
|
65
156
|
|
157
|
+
context "Nested Polymorphic Many" do
|
158
|
+
should "default reader to empty array" do
|
159
|
+
fleet = TrModels::Fleet.new
|
160
|
+
fleet.transports.should == []
|
161
|
+
end
|
162
|
+
|
163
|
+
should "allow adding to association like it was an array" do
|
164
|
+
fleet = TrModels::Fleet.new
|
165
|
+
fleet.transports << TrModels::Car.new
|
166
|
+
fleet.transports.push TrModels::Bus.new
|
167
|
+
fleet.transports.size.should == 2
|
168
|
+
end
|
169
|
+
|
170
|
+
should "store the association" do
|
171
|
+
fleet = TrModels::Fleet.new
|
172
|
+
fleet.transports = [TrModels::Car.new("license_plate" => "DCU2013", "model" => "Honda Civic")]
|
173
|
+
fleet.save.should be_true
|
174
|
+
|
175
|
+
from_db = TrModels::Fleet.find(fleet.id)
|
176
|
+
from_db.transports.size.should == 1
|
177
|
+
from_db.transports[0].license_plate.should == "DCU2013"
|
178
|
+
end
|
179
|
+
|
180
|
+
should "store different associations" do
|
181
|
+
fleet = TrModels::Fleet.new
|
182
|
+
fleet.transports = [
|
183
|
+
TrModels::Car.new("license_plate" => "ABC1223", "model" => "Honda Civic", "year" => 2003),
|
184
|
+
TrModels::Bus.new("license_plate" => "XYZ9090", "max_passengers" => 51),
|
185
|
+
TrModels::Ambulance.new("license_plate" => "HDD3030", "icu" => true)
|
186
|
+
]
|
187
|
+
fleet.save.should be_true
|
188
|
+
|
189
|
+
from_db = TrModels::Fleet.find(fleet.id)
|
190
|
+
from_db.transports.size.should == 3
|
191
|
+
from_db.transports[0].license_plate.should == "ABC1223"
|
192
|
+
from_db.transports[0].model.should == "Honda Civic"
|
193
|
+
from_db.transports[0].year.should == 2003
|
194
|
+
from_db.transports[1].license_plate.should == "XYZ9090"
|
195
|
+
from_db.transports[1].max_passengers.should == 51
|
196
|
+
from_db.transports[2].license_plate.should == "HDD3030"
|
197
|
+
from_db.transports[2].icu.should == true
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
66
201
|
context "Polymorphic Many" do
|
67
202
|
should "default reader to empty array" do
|
68
203
|
catalog = Catalog.new
|
@@ -107,53 +242,6 @@ class AssociationsTest < Test::Unit::TestCase
|
|
107
242
|
end
|
108
243
|
end
|
109
244
|
|
110
|
-
context "Many embedded documents" do
|
111
|
-
should "default reader to empty array" do
|
112
|
-
project = Project.new
|
113
|
-
project.addresses.should == []
|
114
|
-
end
|
115
|
-
|
116
|
-
should "allow adding to association like it was an array" do
|
117
|
-
project = Project.new
|
118
|
-
project.addresses << Address.new
|
119
|
-
project.addresses.push Address.new
|
120
|
-
project.addresses.size.should == 2
|
121
|
-
end
|
122
|
-
|
123
|
-
should "be embedded in document on save" do
|
124
|
-
sb = Address.new(:city => 'South Bend', :state => 'IN')
|
125
|
-
chi = Address.new(:city => 'Chicago', :state => 'IL')
|
126
|
-
project = Project.new
|
127
|
-
project.addresses << sb
|
128
|
-
project.addresses << chi
|
129
|
-
project.save
|
130
|
-
|
131
|
-
from_db = Project.find(project.id)
|
132
|
-
from_db.addresses.size.should == 2
|
133
|
-
from_db.addresses[0].should == sb
|
134
|
-
from_db.addresses[1].should == chi
|
135
|
-
end
|
136
|
-
|
137
|
-
should "allow embedding arbitrarily deep" do
|
138
|
-
@document = Class.new do
|
139
|
-
include MongoMapper::Document
|
140
|
-
key :person, Person
|
141
|
-
end
|
142
|
-
|
143
|
-
meg = Person.new(:name => "Meg")
|
144
|
-
meg.child = Person.new(:name => "Steve")
|
145
|
-
meg.child.child = Person.new(:name => "Linda")
|
146
|
-
|
147
|
-
doc = @document.new(:person => meg)
|
148
|
-
doc.save
|
149
|
-
|
150
|
-
from_db = @document.find(doc.id)
|
151
|
-
from_db.person.name.should == 'Meg'
|
152
|
-
from_db.person.child.name.should == 'Steve'
|
153
|
-
from_db.person.child.child.name.should == 'Linda'
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
245
|
context "Polymorphic Belongs To" do
|
158
246
|
should "default to nil" do
|
159
247
|
status = Status.new
|
@@ -285,5 +373,33 @@ class AssociationsTest < Test::Unit::TestCase
|
|
285
373
|
from_db.person.child.name.should == 'Steve'
|
286
374
|
from_db.person.child.child.name.should == 'Linda'
|
287
375
|
end
|
376
|
+
|
377
|
+
should "allow saving embedded documents in 'many' embedded documents" do
|
378
|
+
@document = Class.new do
|
379
|
+
include MongoMapper::Document
|
380
|
+
|
381
|
+
many :people
|
382
|
+
end
|
383
|
+
|
384
|
+
meg = Person.new(:name => "Meg")
|
385
|
+
sparky = Pet.new(:name => "Sparky", :species => "Dog")
|
386
|
+
koda = Pet.new(:name => "Koda", :species => "Dog")
|
387
|
+
|
388
|
+
doc = @document.new
|
389
|
+
|
390
|
+
meg.pets << sparky
|
391
|
+
meg.pets << koda
|
392
|
+
|
393
|
+
doc.people << meg
|
394
|
+
doc.save
|
395
|
+
|
396
|
+
from_db = @document.find(doc.id)
|
397
|
+
from_db.people.first.name.should == "Meg"
|
398
|
+
from_db.people.first.pets.should_not == []
|
399
|
+
from_db.people.first.pets.first.name.should == "Sparky"
|
400
|
+
from_db.people.first.pets.first.species.should == "Dog"
|
401
|
+
from_db.people.first.pets[1].name.should == "Koda"
|
402
|
+
from_db.people.first.pets[1].species.should == "Dog"
|
403
|
+
end
|
288
404
|
end
|
289
405
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fcoury-mongomapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
@@ -10,7 +10,7 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
|
12
12
|
date: 2009-07-19 00:00:00 -07:00
|
13
|
-
default_executable:
|
13
|
+
default_executable: mmconsole
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -64,8 +64,8 @@ dependencies:
|
|
64
64
|
version:
|
65
65
|
description:
|
66
66
|
email: nunemaker@gmail.com
|
67
|
-
executables:
|
68
|
-
|
67
|
+
executables:
|
68
|
+
- mmconsole
|
69
69
|
extensions: []
|
70
70
|
|
71
71
|
extra_rdoc_files:
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- README.rdoc
|
79
79
|
- Rakefile
|
80
80
|
- VERSION
|
81
|
+
- bin/mmconsole
|
81
82
|
- lib/mongomapper.rb
|
82
83
|
- lib/mongomapper/associations.rb
|
83
84
|
- lib/mongomapper/associations/array_proxy.rb
|
@@ -115,7 +116,7 @@ files:
|
|
115
116
|
- test/test_rails_compatibility.rb
|
116
117
|
- test/test_serializations.rb
|
117
118
|
- test/test_validations.rb
|
118
|
-
has_rdoc:
|
119
|
+
has_rdoc: true
|
119
120
|
homepage: http://github.com/jnunemaker/mongomapper
|
120
121
|
post_install_message:
|
121
122
|
rdoc_options:
|