paulcarey-relaxdb 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +5 -3
- data/Rakefile +1 -1
- data/lib/relaxdb/design_doc.rb +4 -4
- data/lib/relaxdb/document.rb +26 -52
- data/lib/relaxdb/paginate_params.rb +1 -1
- data/lib/relaxdb/paginator.rb +1 -1
- data/lib/relaxdb/query.rb +2 -2
- data/lib/relaxdb/references_many_proxy.rb +4 -5
- data/lib/relaxdb/relaxdb.rb +4 -2
- data/lib/relaxdb/validators.rb +11 -0
- data/lib/relaxdb/views.rb +2 -2
- data/spec/belongs_to_spec.rb +21 -0
- data/spec/derived_properties_spec.rb +12 -0
- data/spec/design_doc_spec.rb +2 -2
- data/spec/document_spec.rb +10 -5
- data/spec/query_spec.rb +3 -3
- data/spec/references_many_spec.rb +45 -5
- data/spec/spec_models.rb +3 -2
- metadata +3 -3
data/README.textile
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
h3. What's New?
|
2
2
|
|
3
|
+
* 02/02/09 - mostly fixes and tweaks for CouchDB trunk (tested against revision 0.9.0a740000). This includes a couple of breaking API changes - count became limit, 409 rather than 412 is returned on document update conflict, and '/' in design docs is treated differently.
|
4
|
+
|
3
5
|
* Potentially breaking change. Skipping validations is now done by adding attribute symbols to an object's list rather than passing them to @save@. For example @my_obj.validation_skip_list << :foo@. This offers per object granularity over validations when working with bulk_save.
|
4
6
|
|
5
7
|
* Potentially breaking change. @load@ now returns an array if passed an array of size one. Previously it would have returned a single object.
|
@@ -96,7 +98,7 @@ h3. Exploring models
|
|
96
98
|
paul.ratings.size # 0
|
97
99
|
|
98
100
|
# Simple views are auto created
|
99
|
-
Rating.all.sorted_by(:thumbs_up) { |q| q.key(2).
|
101
|
+
Rating.all.sorted_by(:thumbs_up) { |q| q.key(2).limit(1) } # query params map directly to CouchDB
|
100
102
|
</code>
|
101
103
|
</pre>
|
102
104
|
|
@@ -110,7 +112,7 @@ h3. Paginating models
|
|
110
112
|
u_id = @user._id
|
111
113
|
|
112
114
|
@posts = Post.paginate_by(page_params, :writer_id, :created_at) do |p|
|
113
|
-
p.startkey([u_id, {}]).endkey([u_id]).descending(true).
|
115
|
+
p.startkey([u_id, {}]).endkey([u_id]).descending(true).limit(5)
|
114
116
|
end
|
115
117
|
render
|
116
118
|
end
|
@@ -132,7 +134,7 @@ h3. Paginating over your own views
|
|
132
134
|
<code>
|
133
135
|
|
134
136
|
RelaxDB.paginate_view(page_params, "Letter", "by_letter_and_number", :letter, :number) do |p|
|
135
|
-
p.startkey(["b"]).endkey(["b", {}]).
|
137
|
+
p.startkey(["b"]).endkey(["b", {}]).limit(2)
|
136
138
|
end
|
137
139
|
|
138
140
|
</code>
|
data/Rakefile
CHANGED
data/lib/relaxdb/design_doc.rb
CHANGED
@@ -29,7 +29,7 @@ module RelaxDB
|
|
29
29
|
|
30
30
|
def save
|
31
31
|
database = RelaxDB.db
|
32
|
-
resp = database.put(
|
32
|
+
resp = database.put(@data["_id"], @data.to_json)
|
33
33
|
@data["_rev"] = JSON.parse(resp.body)["rev"]
|
34
34
|
self
|
35
35
|
end
|
@@ -37,16 +37,16 @@ module RelaxDB
|
|
37
37
|
def self.get(client_class)
|
38
38
|
begin
|
39
39
|
database = RelaxDB.db
|
40
|
-
resp = database.get(
|
40
|
+
resp = database.get("_design/#{client_class}")
|
41
41
|
DesignDocument.new(client_class, JSON.parse(resp.body))
|
42
|
-
rescue
|
42
|
+
rescue HTTP_404
|
43
43
|
DesignDocument.new(client_class, {"_id" => "_design/#{client_class}"} )
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
def destroy!
|
48
48
|
# Implicitly prevent the object from being resaved by failing to update its revision
|
49
|
-
RelaxDB.db.delete("#{
|
49
|
+
RelaxDB.db.delete("#{@data["_id"]}?rev=#{@data["_rev"]}")
|
50
50
|
self
|
51
51
|
end
|
52
52
|
|
data/lib/relaxdb/document.rb
CHANGED
@@ -116,16 +116,15 @@ module RelaxDB
|
|
116
116
|
property :_id
|
117
117
|
property :_rev
|
118
118
|
|
119
|
-
def initialize(
|
120
|
-
hash
|
121
|
-
|
122
|
-
|
123
|
-
self._id = UuidGenerator.uuid
|
119
|
+
def initialize(hash={})
|
120
|
+
unless hash["_id"]
|
121
|
+
self._id = UuidGenerator.uuid
|
122
|
+
end
|
124
123
|
|
125
124
|
@errors = Errors.new
|
126
125
|
@validation_skip_list = []
|
127
126
|
|
128
|
-
# Set default properties if this object
|
127
|
+
# Set default properties if this object isn't being loaded from CouchDB
|
129
128
|
unless hash["_rev"]
|
130
129
|
properties.each do |prop|
|
131
130
|
if methods.include?("set_default_#{prop}")
|
@@ -133,10 +132,10 @@ module RelaxDB
|
|
133
132
|
end
|
134
133
|
end
|
135
134
|
end
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
135
|
+
|
136
|
+
@set_derived_props = hash["_rev"] ? false : true
|
137
|
+
set_attributes(hash)
|
138
|
+
@set_derived_props = true
|
140
139
|
end
|
141
140
|
|
142
141
|
def set_attributes(data)
|
@@ -154,37 +153,7 @@ module RelaxDB
|
|
154
153
|
send("#{key}=".to_sym, val) if methods.include? "#{key}="
|
155
154
|
end
|
156
155
|
end
|
157
|
-
|
158
|
-
# Set the raw attribute values rather than setting via the associated writers
|
159
|
-
# The associated writers may invoke validation functions or set derived values
|
160
|
-
# Such behaviour is unwanted when loading from CouchDB and potentially under
|
161
|
-
# other circumstances
|
162
|
-
def set_raw_attributes(data)
|
163
|
-
data.each do |key, val|
|
164
|
-
if [/_at$/, /_on$/, /_date$/].inject(nil) { |i, r| i ||= (key =~ r) }
|
165
|
-
val = Time.parse(val).utc rescue val
|
166
|
-
end
|
167
|
-
|
168
|
-
if methods.include? "#{key}="
|
169
|
-
key = key.to_sym
|
170
|
-
if properties.include? key
|
171
|
-
instance_variable_set("@#{key}".to_sym, val)
|
172
|
-
elsif self.class.has_one_rels.include? key
|
173
|
-
create_or_get_proxy(HasOneProxy, key).target = val
|
174
|
-
else
|
175
|
-
# belongs_to
|
176
|
-
if key.to_s =~ /_id$/
|
177
|
-
instance_variable_set("@#{key}".to_sym, val)
|
178
|
-
else
|
179
|
-
create_or_get_proxy(BelongsToProxy, key).target = val
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
end
|
185
|
-
|
186
|
-
end
|
187
|
-
|
156
|
+
|
188
157
|
def inspect
|
189
158
|
s = "#<#{self.class}:#{self.object_id}"
|
190
159
|
properties.each do |prop|
|
@@ -229,7 +198,7 @@ module RelaxDB
|
|
229
198
|
begin
|
230
199
|
resp = RelaxDB.db.put(_id, to_json)
|
231
200
|
self._rev = JSON.parse(resp.body)["rev"]
|
232
|
-
rescue
|
201
|
+
rescue HTTP_409
|
233
202
|
on_update_conflict
|
234
203
|
@update_conflict = true
|
235
204
|
return false
|
@@ -367,16 +336,21 @@ module RelaxDB
|
|
367
336
|
@references_many_rels ||= []
|
368
337
|
@references_many_rels << relationship
|
369
338
|
|
339
|
+
id_arr_sym = "@#{relationship}".to_sym
|
340
|
+
|
370
341
|
define_method(relationship) do
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
342
|
+
instance_variable_set(id_arr_sym, []) unless instance_variable_defined? id_arr_sym
|
343
|
+
create_or_get_proxy(ReferencesManyProxy, relationship, opts)
|
344
|
+
end
|
345
|
+
|
346
|
+
define_method("#{relationship}_ids") do
|
347
|
+
instance_variable_set(id_arr_sym, []) unless instance_variable_defined? id_arr_sym
|
348
|
+
instance_variable_get(id_arr_sym)
|
375
349
|
end
|
376
350
|
|
377
351
|
define_method("#{relationship}=") do |val|
|
378
|
-
#
|
379
|
-
instance_variable_set(
|
352
|
+
# Don't invoke this method unless you know what you're doing
|
353
|
+
instance_variable_set(id_arr_sym, val)
|
380
354
|
end
|
381
355
|
end
|
382
356
|
|
@@ -394,7 +368,7 @@ module RelaxDB
|
|
394
368
|
|
395
369
|
define_method("#{relationship}=") do |children|
|
396
370
|
create_or_get_proxy(HasManyProxy, relationship, opts).children = children
|
397
|
-
write_derived_props(relationship)
|
371
|
+
write_derived_props(relationship) if @set_derived_props
|
398
372
|
children
|
399
373
|
end
|
400
374
|
end
|
@@ -414,7 +388,7 @@ module RelaxDB
|
|
414
388
|
|
415
389
|
define_method("#{relationship}=") do |new_target|
|
416
390
|
create_or_get_proxy(HasOneProxy, relationship).target = new_target
|
417
|
-
write_derived_props(relationship)
|
391
|
+
write_derived_props(relationship) if @set_derived_props
|
418
392
|
new_target
|
419
393
|
end
|
420
394
|
end
|
@@ -433,13 +407,13 @@ module RelaxDB
|
|
433
407
|
|
434
408
|
define_method("#{relationship}=") do |new_target|
|
435
409
|
create_or_get_proxy(BelongsToProxy, relationship).target = new_target
|
436
|
-
write_derived_props(relationship)
|
410
|
+
write_derived_props(relationship) if @set_derived_props
|
437
411
|
end
|
438
412
|
|
439
413
|
# Allows all writers to be invoked from the hash passed to initialize
|
440
414
|
define_method("#{relationship}_id=") do |id|
|
441
415
|
instance_variable_set("@#{relationship}_id".to_sym, id)
|
442
|
-
write_derived_props(relationship)
|
416
|
+
write_derived_props(relationship) if @set_derived_props
|
443
417
|
id
|
444
418
|
end
|
445
419
|
|
@@ -2,7 +2,7 @@ module RelaxDB
|
|
2
2
|
|
3
3
|
class PaginateParams
|
4
4
|
|
5
|
-
@@params = %w(key startkey startkey_docid endkey endkey_docid
|
5
|
+
@@params = %w(key startkey startkey_docid endkey endkey_docid limit update descending group reduce include_docs)
|
6
6
|
|
7
7
|
@@params.each do |param|
|
8
8
|
define_method(param.to_sym) do |*val|
|
data/lib/relaxdb/paginator.rb
CHANGED
data/lib/relaxdb/query.rb
CHANGED
@@ -3,7 +3,7 @@ module RelaxDB
|
|
3
3
|
# A Query is used to build the query string made against a view
|
4
4
|
# All parameter values are first JSON encoded and then URL encoded
|
5
5
|
# Nil values are set to the empty string
|
6
|
-
# All parameter calls return self so calls may be chained => q.startkey("foo").endkey("bar").
|
6
|
+
# All parameter calls return self so calls may be chained => q.startkey("foo").endkey("bar").limit(2)
|
7
7
|
|
8
8
|
#
|
9
9
|
# The query object is currently inconsistent with the RelaxDB object idiom. Consider
|
@@ -17,7 +17,7 @@ module RelaxDB
|
|
17
17
|
class Query
|
18
18
|
|
19
19
|
# keys is not included in the standard param as it is significantly different from the others
|
20
|
-
@@params = %w(key startkey startkey_docid endkey endkey_docid
|
20
|
+
@@params = %w(key startkey startkey_docid endkey endkey_docid limit update descending skip group group_level reduce include_docs)
|
21
21
|
|
22
22
|
@@params.each do |param|
|
23
23
|
define_method(param.to_sym) do |*val|
|
@@ -10,6 +10,8 @@ module RelaxDB
|
|
10
10
|
|
11
11
|
@target_class = opts[:class]
|
12
12
|
@relationship_as_viewed_by_target = opts[:known_as].to_s
|
13
|
+
|
14
|
+
@peers = resolve
|
13
15
|
end
|
14
16
|
|
15
17
|
def <<(obj, reciprocal_invocation=false)
|
@@ -30,7 +32,6 @@ module RelaxDB
|
|
30
32
|
end
|
31
33
|
|
32
34
|
def clear
|
33
|
-
resolve
|
34
35
|
@peers.each do |peer|
|
35
36
|
peer.send(@relationship_as_viewed_by_target).send(:delete_from_self, @client)
|
36
37
|
end
|
@@ -53,7 +54,7 @@ module RelaxDB
|
|
53
54
|
end
|
54
55
|
|
55
56
|
def delete_from_self(obj)
|
56
|
-
@peers.delete(obj)
|
57
|
+
@peers.delete(obj)
|
57
58
|
peer_ids.delete(obj._id)
|
58
59
|
end
|
59
60
|
|
@@ -66,12 +67,10 @@ module RelaxDB
|
|
66
67
|
end
|
67
68
|
|
68
69
|
def [](*args)
|
69
|
-
resolve
|
70
70
|
@peers[*args]
|
71
71
|
end
|
72
72
|
|
73
73
|
def each(&blk)
|
74
|
-
resolve
|
75
74
|
@peers.each(&blk)
|
76
75
|
end
|
77
76
|
|
@@ -87,7 +86,7 @@ module RelaxDB
|
|
87
86
|
|
88
87
|
private
|
89
88
|
|
90
|
-
# Resolves the actual ids into real objects via a single GET to CouchDB
|
89
|
+
# Resolves the actual ids into real objects via a single GET to CouchDB
|
91
90
|
def resolve
|
92
91
|
design_doc = @client.class
|
93
92
|
view_name = @relationship
|
data/lib/relaxdb/relaxdb.rb
CHANGED
@@ -58,7 +58,7 @@ module RelaxDB
|
|
58
58
|
obj._rev = new_rev["rev"]
|
59
59
|
obj.post_save
|
60
60
|
end
|
61
|
-
rescue
|
61
|
+
rescue HTTP_409
|
62
62
|
raise UpdateConflict, objs
|
63
63
|
end
|
64
64
|
|
@@ -74,6 +74,8 @@ module RelaxDB
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def load(ids)
|
77
|
+
# RelaxDB.logger.debug(caller.inject("#{db.name}/#{ids}\n") { |a, i| a += "#{i}\n" })
|
78
|
+
|
77
79
|
if ids.is_a? Array
|
78
80
|
resp = db.post("_all_docs?include_docs=true", {:keys => ids}.to_json)
|
79
81
|
data = JSON.parse(resp.body)
|
@@ -174,7 +176,7 @@ module RelaxDB
|
|
174
176
|
klass = data.delete("class")
|
175
177
|
if klass
|
176
178
|
k = Module.const_get(klass)
|
177
|
-
k.new(
|
179
|
+
k.new(data)
|
178
180
|
else
|
179
181
|
# data is not of a known class
|
180
182
|
ViewObject.create(data)
|
data/lib/relaxdb/views.rb
CHANGED
@@ -27,12 +27,12 @@ module RelaxDB
|
|
27
27
|
def self.has_n(target_class, relationship_to_client)
|
28
28
|
template = <<-MAP_FUNC
|
29
29
|
function(doc) {
|
30
|
-
if(doc.class == "${target_class}")
|
30
|
+
if(doc.class == "${target_class}" && doc.${relationship_to_client}_id)
|
31
31
|
emit(doc.${relationship_to_client}_id, doc);
|
32
32
|
}
|
33
33
|
MAP_FUNC
|
34
34
|
template.sub!("${target_class}", target_class)
|
35
|
-
template.
|
35
|
+
template.gsub("${relationship_to_client}", relationship_to_client)
|
36
36
|
end
|
37
37
|
|
38
38
|
def self.has_many_through(target_class, peers)
|
data/spec/belongs_to_spec.rb
CHANGED
@@ -75,6 +75,27 @@ describe RelaxDB::BelongsToProxy do
|
|
75
75
|
r.photo.rating.should == r
|
76
76
|
end
|
77
77
|
|
78
|
+
it "may be used reciprocally" do
|
79
|
+
C1 = Class.new(RelaxDB::Document) do
|
80
|
+
belongs_to :c2
|
81
|
+
end
|
82
|
+
C2 = Class.new(RelaxDB::Document) do
|
83
|
+
belongs_to :c1
|
84
|
+
end
|
85
|
+
i1, i2 = C1.new, C2.new
|
86
|
+
|
87
|
+
i1.c2 = i2
|
88
|
+
i1.save!
|
89
|
+
i2.c1 = i1
|
90
|
+
i2.save!
|
91
|
+
|
92
|
+
i1 = RelaxDB.load i1._id
|
93
|
+
i1.c2.should == i2
|
94
|
+
|
95
|
+
i2 = RelaxDB.load i2._id
|
96
|
+
i2.c1.should == i1
|
97
|
+
end
|
98
|
+
|
78
99
|
describe "validator" do
|
79
100
|
|
80
101
|
it "should be passed the _id and object" do
|
@@ -80,6 +80,18 @@ describe RelaxDB::Document, "derived properties" do
|
|
80
80
|
i.event_name.should == "bar"
|
81
81
|
end
|
82
82
|
|
83
|
+
it "should contintue to be derived post load" do
|
84
|
+
e = DpEvent.new(:name => "shindig").save!
|
85
|
+
i = DpInvite.new(:event => e).save!
|
86
|
+
|
87
|
+
i = RelaxDB.load i._id
|
88
|
+
i.event_name.should == "shindig"
|
89
|
+
|
90
|
+
e = DpEvent.new(:name => "gidnihs").save!
|
91
|
+
i.event = e
|
92
|
+
i.event_name.should == "gidnihs"
|
93
|
+
end
|
94
|
+
|
83
95
|
describe "multiple properties" do
|
84
96
|
|
85
97
|
it "should be derivable from the same source" do
|
data/spec/design_doc_spec.rb
CHANGED
@@ -16,7 +16,7 @@ describe RelaxDB::DesignDocument do
|
|
16
16
|
|
17
17
|
it "should create a corresponding document in CouchDB" do
|
18
18
|
RelaxDB::DesignDocument.get("foo").save
|
19
|
-
RelaxDB.load("_design
|
19
|
+
RelaxDB.load("_design/foo").should_not be_nil
|
20
20
|
end
|
21
21
|
|
22
22
|
end
|
@@ -26,7 +26,7 @@ describe RelaxDB::DesignDocument do
|
|
26
26
|
it "should delete the corresponding document from CouchDB" do
|
27
27
|
dd = RelaxDB::DesignDocument.get("foo").save
|
28
28
|
dd.destroy!
|
29
|
-
RelaxDB.load("_design
|
29
|
+
RelaxDB.load("_design/foo").should be_nil
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
data/spec/document_spec.rb
CHANGED
@@ -46,13 +46,13 @@ describe RelaxDB::Document do
|
|
46
46
|
|
47
47
|
it "may be overridden by inheriting classes" do
|
48
48
|
i = Initiative.new(:x => "y").save
|
49
|
-
i = RelaxDB.load(
|
49
|
+
i = RelaxDB.load("y")
|
50
50
|
i.x.should == "y"
|
51
51
|
i.foo.should == :bar
|
52
52
|
end
|
53
53
|
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
describe "#to_json" do
|
57
57
|
|
58
58
|
it "should not output nil attributes" do
|
@@ -139,7 +139,8 @@ describe RelaxDB::Document do
|
|
139
139
|
User.new(:items => [], :invites_received => [], :invites_sent => [])
|
140
140
|
end
|
141
141
|
|
142
|
-
it
|
142
|
+
# it should issue a single POST
|
143
|
+
it "should issue no PUT requests" do
|
143
144
|
RelaxDB.db.put_count = 0
|
144
145
|
RelaxDB.db.get_count = 0
|
145
146
|
|
@@ -185,10 +186,10 @@ describe RelaxDB::Document do
|
|
185
186
|
|
186
187
|
describe "user defined property writer" do
|
187
188
|
|
188
|
-
it "
|
189
|
+
it "should not be used" do
|
189
190
|
o = BespokeWriter.new(:val => 101).save
|
190
191
|
o = RelaxDB.load o._id
|
191
|
-
o.val.should ==
|
192
|
+
o.val.should == 81
|
192
193
|
end
|
193
194
|
|
194
195
|
end
|
@@ -333,6 +334,10 @@ describe RelaxDB::Document do
|
|
333
334
|
end
|
334
335
|
|
335
336
|
describe "results" do
|
337
|
+
|
338
|
+
it "should be an empty array when no docs match" do
|
339
|
+
Post.all.sorted_by(:subject).should == []
|
340
|
+
end
|
336
341
|
|
337
342
|
it "should be retrievable by exact criteria" do
|
338
343
|
Post.new(:subject => "foo").save
|
data/spec/query_spec.rb
CHANGED
@@ -29,10 +29,10 @@ describe RelaxDB::Query do
|
|
29
29
|
q.view_path.should == "_view//?key=%22olympus%22"
|
30
30
|
end
|
31
31
|
|
32
|
-
it "should honour startkey, endkey and
|
32
|
+
it "should honour startkey, endkey and limit" do
|
33
33
|
q = RelaxDB::Query.new("", "")
|
34
|
-
q.startkey(["olympus"]).endkey(["vesuvius", 3600]).
|
35
|
-
q.view_path.should == "_view//?startkey=%5B%22olympus%22%5D&endkey=%5B%22vesuvius%22%2C3600%5D&
|
34
|
+
q.startkey(["olympus"]).endkey(["vesuvius", 3600]).limit(100)
|
35
|
+
q.view_path.should == "_view//?startkey=%5B%22olympus%22%5D&endkey=%5B%22vesuvius%22%2C3600%5D&limit=100"
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should specify a null key if key was set to nil" do
|
@@ -27,7 +27,37 @@ describe RelaxDB::ReferencesManyProxy do
|
|
27
27
|
t.photos.size.should == 1
|
28
28
|
t.photos[0].should == p
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
|
+
it "should issue only a single request to resolve the relationship" do
|
32
|
+
p, t = Photo.new, Tag.new
|
33
|
+
p.tags << t
|
34
|
+
|
35
|
+
# Create the views
|
36
|
+
p.tags.map { |t| t._id }
|
37
|
+
|
38
|
+
p = RelaxDB.load p._id
|
39
|
+
RelaxDB.db.get_count = 0
|
40
|
+
p.tags.map { |t| t._id }
|
41
|
+
p.tags.map { |t| t._id }
|
42
|
+
RelaxDB.db.get_count.should == 1
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not resolve the relationship when an object is instantiated" do
|
46
|
+
p, t = Photo.new, Tag.new
|
47
|
+
p.tags << t
|
48
|
+
|
49
|
+
RelaxDB.db.get_count = 0
|
50
|
+
p = RelaxDB.load p._id
|
51
|
+
RelaxDB.db.get_count.should == 1
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should make the ids available as a property" do
|
55
|
+
p, t = Photo.new, Tag.new
|
56
|
+
p.tags << t
|
57
|
+
|
58
|
+
p.tags_ids.should == [t._id]
|
59
|
+
end
|
60
|
+
|
31
61
|
describe "#=" do
|
32
62
|
it "should not be invoked" do
|
33
63
|
end
|
@@ -62,6 +92,17 @@ describe RelaxDB::ReferencesManyProxy do
|
|
62
92
|
p.tags.size.should == 1
|
63
93
|
t.photos.size.should == 1
|
64
94
|
end
|
95
|
+
|
96
|
+
it "will resolve the reciprocal relationship" do
|
97
|
+
# Create the views
|
98
|
+
p, t = Photo.new, Tag.new
|
99
|
+
p.tags << t
|
100
|
+
|
101
|
+
p, t = Photo.new, Tag.new
|
102
|
+
RelaxDB.db.get_count = 0
|
103
|
+
p.tags << t
|
104
|
+
RelaxDB.db.get_count.should == 2
|
105
|
+
end
|
65
106
|
|
66
107
|
end
|
67
108
|
|
@@ -81,14 +122,13 @@ describe RelaxDB::ReferencesManyProxy do
|
|
81
122
|
|
82
123
|
describe "owner#destroy" do
|
83
124
|
|
84
|
-
it "
|
85
|
-
# Documentating behaviour, not stating that this behaviour is desired
|
125
|
+
it "should remove its membership from its peers in memory" do
|
86
126
|
p = Photo.new
|
87
127
|
t = Tag.new
|
88
128
|
p.tags << t
|
89
129
|
|
90
130
|
p.destroy!
|
91
|
-
t.photos.size.should ==
|
131
|
+
t.photos.size.should == 0
|
92
132
|
end
|
93
133
|
|
94
134
|
it "should remove its membership from its peers in CouchDB" do
|
@@ -103,7 +143,7 @@ describe RelaxDB::ReferencesManyProxy do
|
|
103
143
|
end
|
104
144
|
|
105
145
|
# Leaving this test as a reminder of problems with all.destroy and a self referential
|
106
|
-
# references_many
|
146
|
+
# references_many
|
107
147
|
#
|
108
148
|
# This test more complex than it needs to be to prove the point
|
109
149
|
# It also serves as a proof of a self referential references_many, but there are better places for that
|
data/spec/spec_models.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paulcarey-relaxdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Carey
|
@@ -9,7 +9,7 @@ autorequire: relaxdb
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-02-02 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -68,7 +68,7 @@ files:
|
|
68
68
|
- lib/relaxdb/server.rb
|
69
69
|
- lib/relaxdb/sorted_by_view.rb
|
70
70
|
- lib/relaxdb/uuid_generator.rb
|
71
|
-
- lib/relaxdb/validators
|
71
|
+
- lib/relaxdb/validators.rb
|
72
72
|
- lib/relaxdb/view_object.rb
|
73
73
|
- lib/relaxdb/view_result.rb
|
74
74
|
- lib/relaxdb/view_uploader.rb
|