mongo_doc 0.6.20 → 0.6.21
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/.rvmrc +0 -1
- data/Gemfile.lock +1 -1
- data/README.textile +1 -1
- data/VERSION +1 -1
- data/lib/mongo_doc/references.rb +2 -2
- data/lib/mongo_doc/references_many.rb +116 -28
- data/lib/mongo_doc.rb +1 -1
- data/mongo_doc.gemspec +2 -2
- data/spec/references_many_spec.rb +134 -28
- metadata +15 -3
data/.rvmrc
CHANGED
data/Gemfile.lock
CHANGED
data/README.textile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.21
|
data/lib/mongo_doc/references.rb
CHANGED
@@ -2,7 +2,7 @@ module MongoDoc
|
|
2
2
|
module References
|
3
3
|
|
4
4
|
# Dereference a DBRef and return the Object
|
5
|
-
def dereference(db_ref)
|
5
|
+
def self.dereference(db_ref)
|
6
6
|
MongoDoc::Collection.new(db_ref.namespace).find_one(db_ref.object_id)
|
7
7
|
end
|
8
8
|
|
@@ -77,7 +77,7 @@ module MongoDoc
|
|
77
77
|
@#{name} ||= if #{name}_ref.nil? # @address ||= if address_name_ref.nil?
|
78
78
|
nil # nil
|
79
79
|
else # else
|
80
|
-
|
80
|
+
References.dereference(#{name}_ref) # References.dereference(address_name_ref)
|
81
81
|
end # end
|
82
82
|
end
|
83
83
|
|
@@ -1,46 +1,134 @@
|
|
1
1
|
module MongoDoc
|
2
2
|
module ReferencesMany
|
3
|
-
|
3
|
+
|
4
|
+
def self.ids_from_objects(objects)
|
5
|
+
if objects.blank?
|
6
|
+
[]
|
7
|
+
else
|
8
|
+
objects.map {|obj| obj._id }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.ids_from_strings_or_ids(ids_or_strings)
|
13
|
+
if ids_or_strings.blank?
|
14
|
+
[]
|
15
|
+
else
|
16
|
+
ids_or_strings.map do |item|
|
17
|
+
if String === item
|
18
|
+
::BSON::ObjectID.cast_from_string(item)
|
19
|
+
else
|
20
|
+
item
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.objects_from_ids(klass, ids)
|
27
|
+
if ids.blank?
|
28
|
+
[]
|
29
|
+
else
|
30
|
+
klass.find(*ids).entries
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.objects_from_refs(refs)
|
35
|
+
if refs.blank?
|
36
|
+
[]
|
37
|
+
else
|
38
|
+
refs.map {|ref| References.dereference(ref) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.refs_from_objects(objects)
|
43
|
+
if objects.blank?
|
44
|
+
[]
|
45
|
+
else
|
46
|
+
objects.map {|obj| ::BSON::DBRef.new(obj.class.collection_name, obj._id) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Declare reference to an array of +Document+s. The references can be
|
51
|
+
# +ObjectID+ references or a +BSON::DBRef+, but cannot be both.
|
52
|
+
#
|
53
|
+
# Use an +ObjectID+ reference when you have a simple reference or will be
|
54
|
+
# referencing a single polymorphic collection. Example:
|
55
|
+
#
|
56
|
+
# +references_many :addresses
|
57
|
+
# +references_many :addresses, :as => :work_address+
|
4
58
|
#
|
5
59
|
# * classname:: name of +Document+ type as an +underscore+ symbol or string
|
6
|
-
# * options:: +:as+ specifies the name of the attribute
|
7
|
-
|
8
|
-
|
9
|
-
|
60
|
+
# * options:: +:as+ specifies the name of the attribute, defaults to
|
61
|
+
# classname
|
62
|
+
#
|
63
|
+
# Use a +BSON::DBRef+ when you need a reference to multiple collections.
|
64
|
+
# Example:
|
65
|
+
#
|
66
|
+
# +references_many :as_ref => :work_address+
|
67
|
+
#
|
68
|
+
# * required:: +:as_ref+ name of the attribute
|
69
|
+
def references_many(*args)
|
70
|
+
options = args.extract_options!
|
71
|
+
|
72
|
+
if options.has_key?(:as_ref)
|
73
|
+
references_many_by_dbref(options[:as_ref].to_s)
|
74
|
+
else
|
75
|
+
klass = args[0].to_s.singularize.camelize
|
76
|
+
references_many_by_id(klass, options[:as].try(:to_s) || klass.demodulize.downcase.pluralize)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def references_many_by_dbref(objects_name)
|
83
|
+
refs_name = "#{objects_name.singularize}_refs"
|
84
|
+
|
85
|
+
_keys << refs_name unless _keys.include?(refs_name)
|
86
|
+
|
87
|
+
module_eval(<<-RUBY, __FILE__, __LINE__)
|
88
|
+
def #{objects_name}=(objects) # def addresses=(objects)
|
89
|
+
@#{objects_name} = objects # @addresses = objects
|
90
|
+
self.#{refs_name} = ReferencesMany.refs_from_objects(objects) # self.address_refs = ReferencesMany.refs_from_objects(objects)
|
91
|
+
end # end
|
92
|
+
|
93
|
+
def #{objects_name} # def addresses
|
94
|
+
@#{objects_name} ||= ReferencesMany.objects_from_refs(#{refs_name}) # @addresses ||= ReferencesMany.objects_from_refs(address_refs)
|
95
|
+
end # end
|
96
|
+
|
97
|
+
def #{refs_name}=(refs) # def address_refs=(refs)
|
98
|
+
@#{objects_name} = nil # @addresses = nil
|
99
|
+
@#{refs_name} = refs # @address_refs = refs
|
100
|
+
end # end
|
101
|
+
|
102
|
+
def #{refs_name} # def address_refs
|
103
|
+
@#{refs_name} ||= [] # @address_refs ||= []
|
104
|
+
end # end
|
105
|
+
RUBY
|
106
|
+
end
|
107
|
+
|
108
|
+
def references_many_by_id(klass, objects_name)
|
10
109
|
ids_name = "#{objects_name.singularize}_ids"
|
11
110
|
|
12
111
|
_keys << ids_name unless _keys.include?(ids_name)
|
13
112
|
|
14
113
|
module_eval(<<-RUBY, __FILE__, __LINE__)
|
15
|
-
def #{objects_name}=(
|
16
|
-
@#{objects_name} =
|
17
|
-
self.#{ids_name} =
|
18
|
-
end
|
19
|
-
|
20
|
-
def #{objects_name}
|
21
|
-
@#{objects_name} ||=
|
22
|
-
|
23
|
-
else # else
|
24
|
-
"#{klass}".constantize. # "Address".constantize.
|
25
|
-
find(*#{ids_name}).entries # find(*address_ids).entries
|
26
|
-
end # end
|
27
|
-
end
|
114
|
+
def #{objects_name}=(objects) # def addresses=(objects)
|
115
|
+
@#{objects_name} = objects # @addresses = objects
|
116
|
+
self.#{ids_name} = ReferencesMany.ids_from_objects(objects) # self.address_ids = ReferencesMany.ids_from_objects(objects)
|
117
|
+
end # end
|
118
|
+
|
119
|
+
def #{objects_name} # def addresses
|
120
|
+
@#{objects_name} ||= ReferencesMany.objects_from_ids(#{klass}, #{ids_name}) # @addresses||= ReferencesMany.objects_from_ids(Address, address_ids)
|
121
|
+
end # end
|
28
122
|
|
29
|
-
def #{ids_name}=(
|
30
|
-
@#{objects_name} = nil
|
31
|
-
@#{ids_name} = ReferencesMany.
|
32
|
-
end
|
123
|
+
def #{ids_name}=(ids_or_strings) # def address_ids=(ids_or_strings)
|
124
|
+
@#{objects_name} = nil # @addresses = nil
|
125
|
+
@#{ids_name} = ReferencesMany.ids_from_strings_or_ids(ids_or_strings) # @address_ids = ReferencesMany.ids_from_strings_or_ids(ids_or_strings)
|
126
|
+
end # end
|
33
127
|
|
34
128
|
def #{ids_name} # def address_ids
|
35
129
|
@#{ids_name} ||= [] # @address_ids ||= []
|
36
130
|
end # end
|
37
131
|
RUBY
|
38
132
|
end
|
39
|
-
|
40
|
-
def self.cast_array(array)
|
41
|
-
array.nil? ? [] : array.map do |item|
|
42
|
-
String === item ? ::BSON::ObjectID.cast_from_string(item) : item
|
43
|
-
end
|
44
|
-
end
|
45
133
|
end
|
46
134
|
end
|
data/lib/mongo_doc.rb
CHANGED
data/mongo_doc.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongo_doc}
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.21"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Les Hill"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-09-01}
|
13
13
|
s.description = %q{ODM for MongoDB}
|
14
14
|
s.email = %q{leshill@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -8,20 +8,21 @@ describe MongoDoc::ReferencesMany do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
context "Simple Reference" do
|
11
|
-
class
|
11
|
+
class PersonSimple
|
12
12
|
include MongoDoc::Document
|
13
13
|
|
14
14
|
references_many :addresses
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
let(:person) { PersonSimple.new }
|
18
|
+
subject { person }
|
18
19
|
|
19
20
|
context "Object accessor" do
|
20
21
|
it { should respond_to(:addresses) }
|
21
22
|
it { should respond_to(:addresses=) }
|
22
23
|
|
23
24
|
it "is not part of the persistent key set" do
|
24
|
-
|
25
|
+
PersonSimple._keys.should_not include('addresses')
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
@@ -30,26 +31,61 @@ describe MongoDoc::ReferencesMany do
|
|
30
31
|
it { should respond_to(:address_ids=) }
|
31
32
|
|
32
33
|
it "is part of the persistent key set" do
|
33
|
-
|
34
|
+
PersonSimple._keys.should include('address_ids')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "setting the ids" do
|
39
|
+
let(:address) { Address.new(:_id => BSON::ObjectID.new) }
|
40
|
+
|
41
|
+
before do
|
42
|
+
person.addresses = [address]
|
43
|
+
end
|
44
|
+
|
45
|
+
context "to nil" do
|
46
|
+
before do
|
47
|
+
person.address_ids = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
its(:address_ids) { should == [] }
|
51
|
+
its(:addresses) { should == [] }
|
52
|
+
end
|
53
|
+
|
54
|
+
context "to []" do
|
55
|
+
before do
|
56
|
+
person.address_ids = []
|
57
|
+
end
|
58
|
+
|
59
|
+
its(:addresses) { should == [] }
|
60
|
+
end
|
61
|
+
|
62
|
+
context "to strings" do
|
63
|
+
before do
|
64
|
+
person.address_ids = [address._id.to_s]
|
65
|
+
end
|
66
|
+
|
67
|
+
its(:address_ids) { should == [address._id] }
|
34
68
|
end
|
35
69
|
end
|
36
70
|
end
|
37
71
|
|
38
72
|
context "Named Reference" do
|
39
|
-
class
|
73
|
+
class PersonNamed
|
40
74
|
include MongoDoc::Document
|
41
75
|
|
42
76
|
references_many :addresses, :as => :known_addresses
|
43
77
|
end
|
44
78
|
|
45
|
-
|
79
|
+
let(:person) { PersonNamed.new }
|
80
|
+
|
81
|
+
subject { person }
|
46
82
|
|
47
83
|
context "Object accessor" do
|
48
84
|
it { should respond_to(:known_addresses) }
|
49
85
|
it { should respond_to(:known_addresses=) }
|
50
86
|
|
51
87
|
it "is not part of the persistent key set" do
|
52
|
-
|
88
|
+
PersonNamed._keys.should_not include('known_addresses')
|
53
89
|
end
|
54
90
|
end
|
55
91
|
|
@@ -58,50 +94,120 @@ describe MongoDoc::ReferencesMany do
|
|
58
94
|
it { should respond_to(:known_address_ids=) }
|
59
95
|
|
60
96
|
it "is part of the persistent key set" do
|
61
|
-
|
97
|
+
PersonNamed._keys.should include('known_address_ids')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "setting the ids" do
|
102
|
+
let(:address) { Address.new(:_id => BSON::ObjectID.new) }
|
103
|
+
|
104
|
+
before do
|
105
|
+
person.known_addresses = [address]
|
106
|
+
end
|
107
|
+
|
108
|
+
context "to nil" do
|
109
|
+
before do
|
110
|
+
person.known_address_ids = nil
|
111
|
+
end
|
112
|
+
|
113
|
+
its(:known_address_ids) { should == [] }
|
114
|
+
its(:known_addresses) { should == [] }
|
115
|
+
end
|
116
|
+
|
117
|
+
context "to []" do
|
118
|
+
before do
|
119
|
+
person.known_address_ids = []
|
120
|
+
end
|
121
|
+
|
122
|
+
its(:known_addresses) { should == [] }
|
123
|
+
end
|
124
|
+
|
125
|
+
context "to strings" do
|
126
|
+
before do
|
127
|
+
person.known_address_ids = [address._id.to_s]
|
128
|
+
end
|
129
|
+
|
130
|
+
its(:known_address_ids) { should == [address._id] }
|
62
131
|
end
|
63
132
|
end
|
64
133
|
end
|
65
134
|
|
66
|
-
|
67
|
-
class
|
135
|
+
context "DBRef reference" do
|
136
|
+
class PersonDBRef
|
68
137
|
include MongoDoc::Document
|
69
138
|
|
70
|
-
references_many :
|
139
|
+
references_many :as_ref => :addresses
|
71
140
|
end
|
72
141
|
|
73
142
|
let(:address) { Address.new(:_id => BSON::ObjectID.new) }
|
74
|
-
let(:person) {
|
143
|
+
let(:person) { PersonDBRef.new }
|
144
|
+
|
145
|
+
subject { person }
|
146
|
+
|
147
|
+
context "Object accessor" do
|
148
|
+
it { should respond_to(:addresses) }
|
149
|
+
it { should respond_to(:addresses=) }
|
150
|
+
|
151
|
+
it "is not part of the persistent key set" do
|
152
|
+
PersonDBRef._keys.should_not include('addresses')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "DBRef accessor" do
|
157
|
+
it { should respond_to(:address_refs) }
|
158
|
+
it { should respond_to(:address_refs=) }
|
159
|
+
|
160
|
+
it "is part of the persistent key set" do
|
161
|
+
PersonDBRef._keys.should include('address_refs')
|
162
|
+
end
|
163
|
+
end
|
75
164
|
|
76
|
-
context "
|
165
|
+
context "setting the collection" do
|
77
166
|
before do
|
78
167
|
person.addresses = [address]
|
79
168
|
end
|
80
169
|
|
81
|
-
|
170
|
+
it "sets the refs to an array of refs]" do
|
171
|
+
person.address_refs.first.namespace.should == Address.collection_name
|
172
|
+
person.address_refs.first.object_id.should == address._id
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context "setting the refs" do
|
177
|
+
before do
|
178
|
+
person.addresses = [address]
|
179
|
+
end
|
180
|
+
|
181
|
+
context "to nil" do
|
82
182
|
before do
|
83
|
-
person.
|
183
|
+
person.address_refs = nil
|
84
184
|
end
|
85
185
|
|
86
|
-
it "sets the
|
87
|
-
person.
|
186
|
+
it "sets the refs to []" do
|
187
|
+
person.address_refs.should == []
|
88
188
|
end
|
89
189
|
|
90
|
-
|
91
|
-
person.addresses.should == []
|
92
|
-
end
|
190
|
+
its(:addresses) { should == [] }
|
93
191
|
end
|
94
192
|
|
95
|
-
|
96
|
-
|
97
|
-
|
193
|
+
context "to []" do
|
194
|
+
before do
|
195
|
+
person.address_refs = []
|
196
|
+
end
|
197
|
+
|
198
|
+
its(:addresses) { should == [] }
|
98
199
|
end
|
99
|
-
end
|
100
200
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
201
|
+
context "to an array of references" do
|
202
|
+
let(:dbref) { ::BSON::DBRef.new(Address.collection_name, address._id) }
|
203
|
+
|
204
|
+
before do
|
205
|
+
person.address_refs = [dbref]
|
206
|
+
end
|
207
|
+
|
208
|
+
it "sets the addresses to nil" do
|
209
|
+
person.instance_variable_get('@addresses').should be_nil
|
210
|
+
end
|
105
211
|
end
|
106
212
|
end
|
107
213
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongo_doc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 45
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 6
|
8
|
-
-
|
9
|
-
version: 0.6.
|
9
|
+
- 21
|
10
|
+
version: 0.6.21
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Les Hill
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-09-01 00:00:00 -04:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
@@ -25,6 +26,7 @@ dependencies:
|
|
25
26
|
requirements:
|
26
27
|
- - ">="
|
27
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 62196427
|
28
30
|
segments:
|
29
31
|
- 3
|
30
32
|
- 0
|
@@ -42,6 +44,7 @@ dependencies:
|
|
42
44
|
requirements:
|
43
45
|
- - ">="
|
44
46
|
- !ruby/object:Gem::Version
|
47
|
+
hash: 62196427
|
45
48
|
segments:
|
46
49
|
- 3
|
47
50
|
- 0
|
@@ -59,6 +62,7 @@ dependencies:
|
|
59
62
|
requirements:
|
60
63
|
- - ">="
|
61
64
|
- !ruby/object:Gem::Version
|
65
|
+
hash: 23
|
62
66
|
segments:
|
63
67
|
- 1
|
64
68
|
- 0
|
@@ -74,6 +78,7 @@ dependencies:
|
|
74
78
|
requirements:
|
75
79
|
- - ">="
|
76
80
|
- !ruby/object:Gem::Version
|
81
|
+
hash: 23
|
77
82
|
segments:
|
78
83
|
- 1
|
79
84
|
- 0
|
@@ -89,6 +94,7 @@ dependencies:
|
|
89
94
|
requirements:
|
90
95
|
- - ">="
|
91
96
|
- !ruby/object:Gem::Version
|
97
|
+
hash: 23
|
92
98
|
segments:
|
93
99
|
- 1
|
94
100
|
- 0
|
@@ -104,6 +110,7 @@ dependencies:
|
|
104
110
|
requirements:
|
105
111
|
- - ">="
|
106
112
|
- !ruby/object:Gem::Version
|
113
|
+
hash: 63
|
107
114
|
segments:
|
108
115
|
- 0
|
109
116
|
- 3
|
@@ -119,6 +126,7 @@ dependencies:
|
|
119
126
|
requirements:
|
120
127
|
- - ">="
|
121
128
|
- !ruby/object:Gem::Version
|
129
|
+
hash: 53
|
122
130
|
segments:
|
123
131
|
- 0
|
124
132
|
- 8
|
@@ -134,6 +142,7 @@ dependencies:
|
|
134
142
|
requirements:
|
135
143
|
- - ">="
|
136
144
|
- !ruby/object:Gem::Version
|
145
|
+
hash: 7
|
137
146
|
segments:
|
138
147
|
- 1
|
139
148
|
- 4
|
@@ -149,6 +158,7 @@ dependencies:
|
|
149
158
|
requirements:
|
150
159
|
- - ">="
|
151
160
|
- !ruby/object:Gem::Version
|
161
|
+
hash: 62196423
|
152
162
|
segments:
|
153
163
|
- 2
|
154
164
|
- 0
|
@@ -345,6 +355,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
345
355
|
requirements:
|
346
356
|
- - ">="
|
347
357
|
- !ruby/object:Gem::Version
|
358
|
+
hash: 3
|
348
359
|
segments:
|
349
360
|
- 0
|
350
361
|
version: "0"
|
@@ -353,6 +364,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
353
364
|
requirements:
|
354
365
|
- - ">="
|
355
366
|
- !ruby/object:Gem::Version
|
367
|
+
hash: 3
|
356
368
|
segments:
|
357
369
|
- 0
|
358
370
|
version: "0"
|