relaxdb 0.3.5 → 0.5

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.
Files changed (49) hide show
  1. data/README.textile +21 -23
  2. data/Rakefile +2 -7
  3. data/docs/spec_results.html +5 -5
  4. data/lib/more/grapher.rb +1 -1
  5. data/lib/relaxdb.rb +3 -5
  6. data/lib/relaxdb/all_delegator.rb +19 -13
  7. data/lib/relaxdb/document.rb +150 -218
  8. data/lib/relaxdb/extlib.rb +7 -1
  9. data/lib/relaxdb/migration.rb +11 -8
  10. data/lib/relaxdb/net_http_server.rb +19 -1
  11. data/lib/relaxdb/paginator.rb +30 -11
  12. data/lib/relaxdb/query.rb +1 -1
  13. data/lib/relaxdb/{belongs_to_proxy.rb → references_proxy.rb} +3 -3
  14. data/lib/relaxdb/relaxdb.rb +87 -7
  15. data/lib/relaxdb/server.rb +8 -2
  16. data/lib/relaxdb/taf2_curb_server.rb +2 -1
  17. data/lib/relaxdb/uuid_generator.rb +38 -2
  18. data/lib/relaxdb/view_by_delegator.rb +34 -0
  19. data/lib/relaxdb/view_object.rb +1 -1
  20. data/lib/relaxdb/view_uploader.rb +16 -2
  21. data/lib/relaxdb/views.rb +23 -55
  22. data/readme.rb +3 -3
  23. data/spec/all_delegator_spec.rb +52 -0
  24. data/spec/callbacks_spec.rb +4 -4
  25. data/spec/derived_properties_spec.rb +4 -4
  26. data/spec/design_doc_spec.rb +2 -2
  27. data/spec/doc_inheritable_spec.rb +2 -2
  28. data/spec/document_spec.rb +47 -25
  29. data/spec/migration_spec.rb +12 -10
  30. data/spec/qpaginate_spec.rb +88 -0
  31. data/spec/query_spec.rb +2 -2
  32. data/spec/references_proxy_spec.rb +94 -0
  33. data/spec/relaxdb_spec.rb +29 -21
  34. data/spec/server_spec.rb +4 -3
  35. data/spec/spec_helper.rb +1 -0
  36. data/spec/spec_models.rb +48 -57
  37. data/spec/uuid_generator_spec.rb +34 -0
  38. data/spec/view_by_spec.rb +62 -54
  39. data/spec/view_docs_by_spec.rb +85 -0
  40. metadata +38 -27
  41. data/lib/more/atomic_bulk_save_support.rb +0 -18
  42. data/lib/relaxdb/has_many_proxy.rb +0 -101
  43. data/lib/relaxdb/has_one_proxy.rb +0 -42
  44. data/lib/relaxdb/references_many_proxy.rb +0 -97
  45. data/spec/belongs_to_spec.rb +0 -124
  46. data/spec/has_many_spec.rb +0 -202
  47. data/spec/has_one_spec.rb +0 -123
  48. data/spec/references_many_spec.rb +0 -173
  49. data/spec/view_spec.rb +0 -23
@@ -11,10 +11,10 @@ describe RelaxDB::Migration do
11
11
  it "should yield each obj to the block and save the result" do
12
12
  Primitives.new(:num => 5).save!
13
13
  r = @mig.run Primitives do |p|
14
- pn = Primitives.new(:num => p.num * 2)
15
- [p, pn]
14
+ p.num *= 2
15
+ p
16
16
  end
17
- Primitives.by_num.map { |p| p.num}.should == [5, 10]
17
+ Primitives.by_num.map { |p| p.num }.should == [10]
18
18
  end
19
19
 
20
20
  it "should raise an exception if a save results in a conflict" do
@@ -42,16 +42,18 @@ describe RelaxDB::Migration do
42
42
  RelaxDB.db.reset_req_count
43
43
  end
44
44
 
45
- # Note: two extra requests per paginate_view request are required
45
+ # Note: three requests per migration loop, plus one for the final loop
46
+ # where no migration actually occurs. (It would be two for the final
47
+ # loop except a request isn't isn't the id array passed to load is empty)
46
48
  it "should operate on a doc set of the given size aka limit" do
47
49
  @mig.run(Primitives, 1) { |p| p.num *= p.num; p }
48
- RelaxDB.db.req_count.should == 10 + 5 * 2
50
+ RelaxDB.db.req_count.should == 5 * 3 + 1
49
51
  Primitives.by_num.map { |p| p.num }.should == [1, 4, 9, 16, 25]
50
52
  end
51
53
 
52
54
  it "should operate on a doc set of default size" do
53
55
  @mig.run(Primitives) { |p| p.num *= p.num; p }
54
- RelaxDB.db.req_count.should == 2 + 1 * 2
56
+ RelaxDB.db.req_count.should == 1 * 3 + 1
55
57
  Primitives.by_num.map { |p| p.num }.should == [1, 4, 9, 16, 25]
56
58
  end
57
59
 
@@ -66,7 +68,7 @@ describe RelaxDB::Migration do
66
68
  describe ".run_all" do
67
69
 
68
70
  it "should save the version after each successful migration" do
69
- @mig.run_all "a/b/1_", lambda {}
71
+ @mig.run_all ["a/b/1_"], lambda { |o| }
70
72
  RelaxDB::MigrationVersion.version.should == 1
71
73
  end
72
74
 
@@ -74,7 +76,7 @@ describe RelaxDB::Migration do
74
76
  v = RelaxDB::MigrationVersion.retrieve
75
77
  v.version = 2
76
78
  v.save!
77
- @mig.run_all "3_", lambda {}
79
+ @mig.run_all ["3_"], lambda { |o| }
78
80
  RelaxDB::MigrationVersion.version.should == 3
79
81
  end
80
82
 
@@ -82,13 +84,13 @@ describe RelaxDB::Migration do
82
84
  v = RelaxDB::MigrationVersion.retrieve
83
85
  v.version = 2
84
86
  v.save!
85
- @mig.run_all "1_foo", lambda {}
87
+ @mig.run_all ["1_foo"], lambda { |o| }
86
88
  RelaxDB::MigrationVersion.version.should == 2
87
89
  end
88
90
 
89
91
  it "should raise an exception on failure" do
90
92
  lambda do
91
- @mig.run_all "1_foo", lambda { raise "Expected" }
93
+ @mig.run_all ["1_foo"], lambda { |o| raise "Expected" }
92
94
  end.should raise_error(RuntimeError, "Expected")
93
95
  end
94
96
 
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require File.dirname(__FILE__) + '/spec_models.rb'
3
+
4
+ describe "RelaxDB Pagination" do
5
+
6
+ before(:each) do
7
+ setup_test_db
8
+
9
+ letters = [
10
+ ["a", 1], ["a", 2], ["a", 3],
11
+ ["b", 1], ["b", 2], ["b", 3], ["b", 4], ["b", 5],
12
+ ["c", 1], ["c", 2]
13
+ ].map { |o| Letter.new :letter => o[0], :number => o[1], :_id => "#{o[0]}#{o[1]}" }
14
+
15
+ RelaxDB.bulk_save *letters
16
+ end
17
+
18
+ # helper function
19
+ def s(letters)
20
+ letters.map { |l| "#{l.letter}#{l.number}"}.join(", ")
21
+ end
22
+
23
+ def n(letters)
24
+ letters.map { |l| "#{l.number}"}.join(", ")
25
+ end
26
+
27
+ describe "functional tests" do
28
+
29
+ it "should navigate through a series" do
30
+ query = lambda do |page_params|
31
+ RelaxDB.qpaginate_view "Letter_by_letter_and_number", :page_params => page_params,
32
+ :startkey => ["a"], :endkey => ["a",{}], :limit => 2,
33
+ :attributes => [:letter, :number]
34
+ end
35
+
36
+ letters = query.call({})
37
+ s(letters).should == "a1, a2"
38
+ letters.prev_params.should be_false
39
+
40
+ letters = query.call(letters.next_params)
41
+ s(letters).should == "a3"
42
+ letters.next_params.should be_false
43
+
44
+ letters = query.call(letters.prev_params)
45
+ s(letters).should == "a1, a2"
46
+ letters.next_params.should be
47
+ end
48
+
49
+ end
50
+
51
+ describe "Non emitted docs" do
52
+
53
+ before(:each) do
54
+ map = <<-FUNC
55
+ function (doc) {
56
+ if (doc.relaxdb_class === "Letter") {
57
+ emit([doc.letter, doc.number], null);
58
+ }
59
+ }
60
+ FUNC
61
+
62
+ view_name = "Letter_by_letter_and_number_v2"
63
+ RelaxDB::DesignDocument.get(RelaxDB.dd).add_map_view(view_name, map).save
64
+ end
65
+
66
+ it "should navigate through a series when 1 emitted as val" do
67
+ query = lambda do |page_params|
68
+ RelaxDB.qpaginate_docs "Letter_by_letter_and_number_v2", :page_params => page_params,
69
+ :startkey => ["a"], :endkey => ["a",{}], :limit => 2,
70
+ :attributes => [:letter, :number]
71
+ end
72
+
73
+ letters = query.call({})
74
+ s(letters).should == "a1, a2"
75
+ letters.prev_params.should be_false
76
+
77
+ letters = query.call(letters.next_params)
78
+ s(letters).should == "a3"
79
+ letters.next_params.should be_false
80
+
81
+ letters = query.call(letters.prev_params)
82
+ s(letters).should == "a1, a2"
83
+ letters.next_params.should be
84
+ end
85
+
86
+ end
87
+
88
+ end
data/spec/query_spec.rb CHANGED
@@ -10,12 +10,12 @@ describe RelaxDB::Query do
10
10
  describe "#view_name" do
11
11
 
12
12
  it "should match a single key attribute" do
13
- q = RelaxDB::ViewCreator.by_att_list ["bar"], :foo
13
+ q = RelaxDB::ViewCreator.docs_by_att_list ["bar"], :foo
14
14
  q.view_name.should == "bar_by_foo"
15
15
  end
16
16
 
17
17
  it "should match key attributes" do
18
- q = RelaxDB::ViewCreator.by_att_list ["bar"], :foo, :bar
18
+ q = RelaxDB::ViewCreator.docs_by_att_list ["bar"], :foo, :bar
19
19
  q.view_name.should == "bar_by_foo_and_bar"
20
20
  end
21
21
  end
@@ -0,0 +1,94 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require File.dirname(__FILE__) + '/spec_models.rb'
3
+
4
+ describe RelaxDB::ReferencesProxy do
5
+
6
+ before(:all) do
7
+ setup_test_db
8
+ end
9
+
10
+ describe "references" do
11
+
12
+ it "should return nil when accessed before assignment" do
13
+ r = Rating.new
14
+ r.photo.should == nil
15
+ end
16
+
17
+ it "should be establishable via constructor attribute" do
18
+ p = Photo.new
19
+ r = Rating.new :photo => p
20
+ r.photo.should == p
21
+ end
22
+
23
+ it "should be establishable via constructor id" do
24
+ p = Photo.new.save
25
+ r = Rating.new :photo_id => p._id
26
+ r.photo.should == p
27
+ end
28
+
29
+ it "should return the same object on repeated invocations" do
30
+ p = Photo.new.save
31
+ r = Rating.new(:photo => p).save
32
+ r = RelaxDB.load(r._id)
33
+ r.photo.object_id.should == r.photo.object_id
34
+ end
35
+
36
+ it "may be used reciprocally across save / load boundary" do
37
+ fb, bf = FooBar.new, BarFoo.new
38
+
39
+ fb.bf = bf
40
+ fb.save!
41
+ bf.fb = fb
42
+ bf.save!
43
+
44
+ fb = RelaxDB.load fb._id
45
+ fb.bf.should == bf
46
+
47
+ bf = RelaxDB.load bf._id
48
+ bf.fb.should == fb
49
+ end
50
+
51
+ it "should not store the referenced object" do
52
+ p = Photo.new.save!
53
+ r = Rating.new(:photo => p).save!
54
+
55
+ r = RelaxDB.reload r
56
+ RelaxDB.db.reset_req_count
57
+
58
+ r.data["photo"].should be_nil
59
+ r.photo.should == p
60
+
61
+ RelaxDB.db.req_count.should == 1
62
+ end
63
+
64
+ describe "validator" do
65
+
66
+ it "should be passed the _id and object" do
67
+ a = Atom.new(:_id => "atom").save!
68
+ c = Class.new(RelaxDB::Document) do
69
+ references :foo, :validator => lambda { |foo_id, obj| foo_id.reverse == obj._id }
70
+ end
71
+ c.new(:_id => "mota", :foo => a).save!
72
+ end
73
+
74
+ it "may be used with a predefined validator" do
75
+ c = Class.new(RelaxDB::Document) do
76
+ references :foo, :validator => :required
77
+ end
78
+ c.new.save.should be_false
79
+ end
80
+
81
+ it "should be provided with a default error message when validation fails" do
82
+ c = Class.new(RelaxDB::Document) do
83
+ references :foo, :validator => :required
84
+ end
85
+ x = c.new
86
+ x.save
87
+ x.errors[:foo].should_not be_blank
88
+ end
89
+
90
+ end
91
+
92
+ end
93
+
94
+ end
data/spec/relaxdb_spec.rb CHANGED
@@ -10,7 +10,7 @@ describe RelaxDB do
10
10
  describe ".create_object" do
11
11
 
12
12
  it "should return an instance of a known object if passed a hash with a class key" do
13
- data = { "relaxdb_class" => "Item" }
13
+ data = { "relaxdb_class" => "Item", "_rev" => "" }
14
14
  obj = RelaxDB.create_object(data)
15
15
  obj.should be_instance_of(Item)
16
16
  end
@@ -68,7 +68,7 @@ describe RelaxDB do
68
68
 
69
69
  it "should save non conflicting docs and mark conflicting docs" do
70
70
  p1, p2 = Atom.new.save!, Atom.new.save!
71
- p1.dup.save!
71
+ Atom.new(:_id => p1._id, :_rev => p1._rev).save!
72
72
  RelaxDB.bulk_save p1, p2
73
73
  p1._rev.should =~ /1-/
74
74
  p1.should be_update_conflict
@@ -85,7 +85,7 @@ describe RelaxDB do
85
85
  describe "all-or-nothing" do
86
86
  it "should save non conflicting and conflicting docs" do
87
87
  p1, p2 = Primitives.new(:num => 1).save!, Primitives.new(:num => 2).save!
88
- p1d = p1.dup
88
+ p1d = Primitives.new("_id" => p1._id, "_rev" => p1._rev, "relaxdb_class" => "Primitives")
89
89
  p1d.num = 11
90
90
  p1d.save!
91
91
  p1.num = 6
@@ -143,7 +143,7 @@ describe RelaxDB do
143
143
 
144
144
  it "should raise an exception on document conflict after all docs have been processed" do
145
145
  p1, p2 = Atom.new.save!, Atom.new.save!
146
- p1.dup.save!
146
+ Atom.new(:_id => p1._id, :_rev => p1._rev).save!
147
147
  lambda { RelaxDB.bulk_save!(p1, p2) }.should raise_error(RelaxDB::UpdateConflict)
148
148
  p2._rev.should =~ /2-/
149
149
  end
@@ -162,7 +162,11 @@ describe RelaxDB do
162
162
  orig = "relaxdb_spec"
163
163
  replica = "relaxdb_spec_replicate_test"
164
164
  RelaxDB.delete_db replica rescue :ok
165
- class ReplicaTest < RelaxDB::Document; end
165
+
166
+ RelaxDB.enable_view_creation
167
+ class ::ReplicaTest < RelaxDB::Document; end
168
+ RelaxDB::View.design_doc.save
169
+
166
170
  ReplicaTest.new.save # implicitly saved to orig
167
171
  RelaxDB.replicate_db orig, replica
168
172
  RelaxDB.use_db replica
@@ -261,8 +265,17 @@ describe RelaxDB do
261
265
  res.first._id.should == "x"
262
266
  end
263
267
 
268
+ it "should leave relaxdb_class param intact" do
269
+ RelaxDB::DesignDocument.get(RelaxDB.dd).add_view("simple", "map", map_func).save
270
+ a = Atom.new.save!
271
+ la = RelaxDB.view("simple").first
272
+ la.should == a
273
+ la.save!
274
+ RelaxDB.load! la._id
275
+ end
276
+
264
277
  it "should be queryable with a multi key post" do
265
- Primitives.view_by :num
278
+ Primitives.view_docs_by :num
266
279
 
267
280
  5.times { |i| Primitives.new(:num => i).save }
268
281
  Primitives.by_num
@@ -271,18 +284,18 @@ describe RelaxDB do
271
284
  end
272
285
 
273
286
  it "should return nil for a reduce view with no results" do
274
- Primitives.view_by :num
287
+ Primitives.view_docs_by :num
275
288
  RelaxDB.view("Primitives_by_num", :reduce => true).should be_nil
276
289
  end
277
290
 
278
291
  it "should return a single value for a reduce view with a single result" do
279
- Primitives.view_by :num
292
+ Primitives.view_docs_by :num
280
293
  Primitives.new(:num => :x).save!
281
294
  RelaxDB.view("Primitives_by_num", :reduce => true).should == 1
282
295
  end
283
296
 
284
297
  it "should return an array for a reduce view with multiple results" do
285
- Primitives.view_by :num
298
+ Primitives.view_docs_by :num
286
299
  2.times { |i| Primitives.new(:num => i).save! }
287
300
  res = RelaxDB.view("Primitives_by_num", :reduce => true, :group => true)
288
301
  res.should be_an_instance_of(Array)
@@ -320,10 +333,7 @@ describe RelaxDB do
320
333
  RelaxDB.enable_view_creation false
321
334
 
322
335
  class CvdBar < RelaxDB::Document
323
- view_by :foo
324
- has_one :foo1
325
- has_many :foon
326
- references_many :foor
336
+ view_docs_by :foo
327
337
  end
328
338
  end
329
339
 
@@ -339,21 +349,19 @@ describe RelaxDB do
339
349
  before(:each) do
340
350
  create_test_db
341
351
 
342
- class CveBar < RelaxDB::Document
343
- view_by :foo
344
- has_one :foo1
345
- has_many :foon
346
- references_many :foor
352
+ RelaxDB.enable_view_creation
353
+
354
+ class ::CveBar < RelaxDB::Document
355
+ view_docs_by :foo
347
356
  end
357
+
358
+ RelaxDB::View.design_doc.save
348
359
  end
349
360
 
350
361
  it "should create all views" do
351
362
  dd = RelaxDB::DesignDocument.get "spec_doc"
352
363
  dd.data["views"]["CveBar_all"].should be
353
364
  dd.data["views"]["CveBar_by_foo"].should be
354
- dd.data["views"]["CveBar_foo1"].should be
355
- dd.data["views"]["CveBar_foon"].should be
356
- dd.data["views"]["CveBar_foor"].should be
357
365
  end
358
366
 
359
367
  end
data/spec/server_spec.rb CHANGED
@@ -20,11 +20,12 @@ describe RelaxDB do
20
20
  @server.get "/relaxdb_spec/foo"
21
21
  end.should raise_error(RelaxDB::HTTP_404)
22
22
  end
23
-
24
- it "should raise a RuntimeError for non specific errors" do
23
+
24
+ # Possibly redundant - a RelaxDB::HTTP_404 is raised with CouchDB 0.11
25
+ it "should raise an error for non specific errors" do
25
26
  lambda do
26
27
  @server.get "/relaxdb_spec/_design/spec_doc/_view?fail=true"
27
- end.should raise_error(RuntimeError)
28
+ end.should raise_error
28
29
  end
29
30
 
30
31
  end
data/spec/spec_helper.rb CHANGED
@@ -44,6 +44,7 @@ def create_base_db
44
44
  RelaxDB.use_db "relaxdb_spec_base"
45
45
  RelaxDB.enable_view_creation
46
46
  require File.dirname(__FILE__) + '/spec_models.rb'
47
+ RelaxDB::View.design_doc.save
47
48
  puts "Created relaxdb_spec_base"
48
49
  end
49
50
 
data/spec/spec_models.rb CHANGED
@@ -1,3 +1,11 @@
1
+ class FooBar < RelaxDB::Document
2
+ references :bf
3
+ end
4
+
5
+ class BarFoo < RelaxDB::Document
6
+ references :fb
7
+ end
8
+
1
9
  class Atom < RelaxDB::Document
2
10
  end
3
11
 
@@ -19,9 +27,11 @@ class Primitives < RelaxDB::Document
19
27
  property :false_bool
20
28
  property :created_at
21
29
  property :updated_at
22
- property :empty
30
+ property :context
23
31
 
24
- view_by :num
32
+ view_docs_by :num
33
+
34
+ view_by :str
25
35
 
26
36
  end
27
37
 
@@ -30,31 +40,30 @@ end
30
40
 
31
41
  class BespokeReader < RelaxDB::Document
32
42
  property :val
33
- def val; @val + 5; end
43
+ def val; @data["val"] + 5; end
34
44
  end
35
45
 
36
46
  class BespokeWriter < RelaxDB::Document
37
47
  property :val
38
48
  property :tt
39
- def val=(v); @val = v - 10; end
40
- def tt=(t); @tt = t.is_a?(String) ? Time.parse(t) : t; end
49
+ def val=(v); data["val"] = v - 10; end
41
50
  end
42
51
 
43
52
  class Invite < RelaxDB::Document
44
53
 
45
54
  property :message
46
55
 
47
- belongs_to :sender
48
- belongs_to :recipient
56
+ references :sender
57
+ references :recipient
49
58
 
50
59
  end
51
60
 
52
61
  class Item < RelaxDB::Document
53
62
 
54
63
  property :name
55
- belongs_to :user
64
+ references :user
56
65
 
57
- view_by :user_id
66
+ view_docs_by :user_id
58
67
 
59
68
  end
60
69
 
@@ -62,13 +71,8 @@ class User < RelaxDB::Document
62
71
 
63
72
  property :name, :default => "u"
64
73
  property :age
65
-
66
- has_many :items, :class => "Item"
67
-
68
- has_many :invites_received, :class => "Invite", :known_as => :recipient
69
- has_many :invites_sent, :class => "Invite", :known_as => :sender
70
74
 
71
- view_by :name, :age
75
+ view_docs_by :name, :age
72
76
 
73
77
  end
74
78
 
@@ -79,18 +83,18 @@ class Post < RelaxDB::Document
79
83
  property :created_at
80
84
  property :viewed_at
81
85
 
82
- view_by :content
83
- view_by :subject
84
- view_by :viewed_at
86
+ view_docs_by :content
87
+ view_docs_by :subject
88
+ view_docs_by :viewed_at
85
89
 
86
90
  end
87
91
 
88
92
  class Rating < RelaxDB::Document
89
93
 
90
94
  property :stars, :default => 5
91
- belongs_to :photo
95
+ references :photo
92
96
 
93
- view_by :stars
97
+ view_docs_by :stars
94
98
 
95
99
  end
96
100
 
@@ -98,63 +102,32 @@ class Photo < RelaxDB::Document
98
102
 
99
103
  property :name
100
104
 
101
- has_one :rating
102
-
103
- references_many :tags, :class => "Tag", :known_as => :photos
104
-
105
- has_many :taggings, :class => "Tagging"
106
-
107
105
  end
108
106
 
109
107
  class Tag < RelaxDB::Document
110
108
 
111
109
  property :name
112
- references_many :photos, :class => "Photo", :known_as => :tags
113
-
114
- has_many :taggings, :class => "Tagging"
115
110
 
116
111
  end
117
112
 
118
113
  class Tagging < RelaxDB::Document
119
114
 
120
- belongs_to :photo
121
- belongs_to :tag
115
+ references :photo
116
+ references :tag
122
117
  property :relevance
123
118
 
124
119
  end
125
120
 
126
- class MultiWordClass < RelaxDB::Document
127
- has_one :multi_word_child
128
- has_many :multi_word_children, :class => "MultiWordChild"
129
- end
130
-
131
- class MultiWordChild < RelaxDB::Document
132
- belongs_to :multi_word_class
133
- end
134
-
135
- class TwitterUser < RelaxDB::Document
136
-
137
- property :name
138
- references_many :followers, :class => "User", :known_as => :leaders
139
- references_many :leaders, :class => "User", :known_as => :followers
140
-
141
- end
142
-
143
- class Dysfunctional < RelaxDB::Document
144
- has_one :failure
145
- has_many :failures, :class => "Failure"
146
- end
147
-
148
121
  class Failure < RelaxDB::Document
149
122
  property :pathological, :validator => lambda { false }
150
- belongs_to :dysfunctional
123
+ references :dysfunctional
151
124
  end
152
125
 
153
126
  class Letter < RelaxDB::Document
154
127
  property :letter
155
128
  property :number
156
- view_by :letter, :number
157
- view_by :number
129
+ view_docs_by :letter, :number
130
+ view_docs_by :number
158
131
  end
159
132
 
160
133
  class Ancestor < RelaxDB::Document
@@ -168,7 +141,7 @@ class Ancestor < RelaxDB::Document
168
141
  property :user_name,
169
142
  :derived => [:user, lambda { |p, o| o.user.name } ]
170
143
 
171
- view_by :x
144
+ view_docs_by :x
172
145
  end
173
146
 
174
147
  class Descendant < Ancestor
@@ -185,6 +158,24 @@ class RichDescendant < Descendant
185
158
  :derived => [:ukulele, lambda { |p, o| o.ukulele.name } ]
186
159
  end
187
160
 
161
+ class Contrived < RelaxDB::Document
162
+
163
+ attr_accessor :context_count
164
+ def initialize params = {}
165
+ @context_count = 0
166
+ super
167
+ end
168
+
169
+ property :foo,
170
+ :default => 5,
171
+ :derived => [
172
+ :context,
173
+ lambda { |f, c| c.context_count += 1; 10 }
174
+ ]
175
+
176
+ references :context
177
+ end
178
+
188
179
  module Inh
189
180
 
190
181
  class X < RelaxDB::Document; end