mongo_doc 0.6.20 → 0.6.21
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|