Ruby on Rails Saturday, December 25, 2010

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

--
Posted via http://www.ruby-forum.com/.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

No comments:

Post a Comment