paulcarey-relaxdb 0.2.7 → 0.2.8
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/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
|