Revision 363533633036 () - Diff

Link to this snippet: https://friendpaste.com/744xr8OvLiBlG5lEhXYrfQ
Embed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
require 'rubygems'
require 'relaxdb'

# Specify the db to be used. Create it in CouchDB yourself locally.

RelaxDB::Database.set_std_db :host => "localhost", :port => 5984, :db => "photos"

#
# Define the classes
#

class Photo < RelaxDB::Document
property :name
property :tags

end

class Tag < RelaxDB::Document
property :name
property :photos
end

#
# Create the views
#

tags_view = <<MAP_FUNC
function(doc) {
if(doc.class == "Tag" && doc.photos) {
var i;
for(i = 0; i < doc.photos.length; i++) {
emit(doc.photos[i], doc);
}
}
}
MAP_FUNC

photos_view = <<MAP_FUNC
function(doc) {
if(doc.class == "Photo" && doc.tags) {
var i;
for(i = 0; i < doc.tags.length; i++) {
emit(doc.tags[i], doc);
}
}
}
MAP_FUNC

DesignDocument.get(Photo).add_view_to_data("all_tags", tags_view).save
DesignDocument.get(Tag).add_view_to_data("all_photos", photos_view).save

#
# Insert some data
#

Photo.destroy_all!
Tag.destroy_all!

mg = Photo.new(:_id => "mg", :name => "Migration").save
des = Photo.new(:_id => "des", :name => "Dar es Salaam").save

wd = Tag.new(:_id => "wd", :name => "wildebeest").save
tz = Tag.new(:_id => "tz", :name => "tanzania").save

# Being forced to use ids and set the relationship on both sides is clunky and error
# prone, but it's no more than a current limitation of the library

mg.tags = [wd._id, tz._id]
des.tags = [tz._id]

wd.photos = [mg._id]
tz.photos = [mg._id, des._id]

RelaxDB.bulk_save(mg, des, wd, tz)

#
# Examine the data, confirm in the CouchDB log that n+1 requests aren't being made
#

mg = Photo.all_by(:name) { |q| q.key = "Migration"}[0]
mg_tags = Photo.view("all_tags?key=\"#{mg._id}\"")
puts mg_tags.inject("Tags for #{mg.name}") { |m, t| m << " '#{t.name}'" }

tz = Tag.all_by(:name) { |q| q.key = "tanzania" }[0]
tz_photos = Tag.view("all_photos?key=\"#{tz._id}\"")
puts tz_photos.inject("Photos for #{tz.name}") { |m, p| m << " '#{p.name}'" }