Ruby, Sequel and Trees
Posted by Stephan on 28. July 2009
While working on some tree structure a couple of unit tests failed, when creating some form of summary of said tree structure. First of all here’s a condensed form of the code:
require 'sequel'
DB = Sequel.sqlite
DB.create_table :items do
primary_key :id
String :name
String :foo, :default => 'NOT SET'
Integer :item_id
end
class Item < Sequel::Model
one_to_many :items
def summary
if items.empty?
return [ { self.name => self.foo } ]
else
items.inject( [] ){ | r, sub_res | r << sub_res.summary }
end
end
end
r1 = Item.create :name => 'R1'
r2 = Item.create :name => 'R2'
r1.add_item r2
r2.foo = 'Ding'
#r2.save
[ r1, r2 ].each{ |i|
puts "Item : #{ i.id }"
puts "Direct Foo: #{ i.foo.inspect }"
puts "Summary : #{ i.summary.inspect }"
puts
}
Notice, that I’ve commented out saving r2. The output is:
Item : 1
Direct Foo: "NOT SET"
Summary : [[{"R2"=>"NOT SET"}]]
Item : 2
Direct Foo: "Ding"
Summary : [{"R2"=>"Ding"}]
What I didn’t expect – and why the unit tests failed – is the ‘NOT SET’ in the r1 summary.
One way to end up with what I originally expected is to save r2. Another way is to set r2.foo before adding r1 to r1:
r2.foo = 'Ding' r1.add_item r2
How ever I’m still not sure whether this is intended behaviour and why it should behave like this. (If it is, I’d like to know why.)
What do you think?









