Devin:
Unsolicited, but here's a pair of classes I've used for representing
"vertices" (nodes) and "edges" (node links). You could conceptually
"Vertex".gsub("NodeLink") and "Edge".gsub("Node") and get 80% of where
you want to get. The useful bits:
- the belongs_to clauses in Edge implement the kind of thing you're
describing
- the before_destroy clause in Vertex takes the place of dependent =>
destroy
- the edges method in Vertex finds both "left" and "right" links.
Also, this is a self-contained sample useful for testing, since it
includes the up() and down() methods to create and destroy the tables
while you're trying things out. I use this pattern a lot.
The example does NOT check for circular dependencies and such (since
edges and vertices may describe circular graphs), but you might find it
helpful.
class Edge < ActiveRecord::Base
belongs_to :vertex_a, :class_name => 'Vertex', :foreign_key =>
'vertex_a_id'
belongs_to :vertex_b, :class_name => 'Vertex', :foreign_key =>
'vertex_b_id'
def self.up()
ActiveRecord::Schema.define do
create_table "edges", :force => true do |t|
t.integer "vertex_a_id"
t.integer "vertex_b_id"
end
end
end
def self.down()
ActiveRecord::Schema.define do
drop_table :edges
end
end
end
class Vertex < ActiveRecord::Base
before_destroy do |record|
Edge.destroy_all "vertex_a_id = #{record.id}"
Edge.destroy_all "vertex_b_id = #{record.id}"
end
# has_many :vertices will not work in this case, so here's
# how we find all edges asociated with this vertex...
def edges
Edge.find_all_by_vertex_a_id(self.id) +
Edge.find_all_by_vertex_b_id(self.id)
end
has_many :vertices
def self.up()
ActiveRecord::Schema.define do
create_table "vertices", :force => true do |t|
t.float "x"
t.float "y"
t.float "z"
end
end
end
def self.down()
ActiveRecord::Schema.define do
drop_table :vertices
end
end
end
# Testing...
def setup
Edge.up
Vertex.up
v0 = Vertex.create(:x => 0.0, :y => 0.0, :z => 0.0)
v1 = Vertex.create(:x => 1.0, :y => 1.0, :z => 1.0)
e0 = Edge.create(:vertex_a => v0, :vertex_b => v1)
[v0, v1, e0]
end
def teardown
Edge.down
Vertex.down
end