Need help with self-referencing models and relationships

Okay,

I have the site running (http://www.londonprogressivejournal.com) and if you look you can 'respond' to any given article which leads to you submitting a 'letter' object to the system.

At a later date we'll be publishing these.

Articles can of course have many letters. Letters only have one article.

However, people will be able to respond to a published letter just as they will to an article.

So a Letter can have many letters (those that are responses to it)...but it also only has one letter if it is itself a response to an existing letter.

My Letter model has both an article_id and a letter_id but my issue is how to show Ruby that model? I have said 'has many letters' but now of course I can't refer to letter.letter.id to find out which letter this one might be a response to.

Does anyone know how to deal with this sort of self-referential architecture in ruby?

Cheers Theo

You can define these relationships yourself using something like this: class Letter < ActiveRecord::Base   belongs_to :article   belongs_to :parent, :foreign_key => 'parent_id', :class_name => 'Letter'   has_many :children, :foreign_key => 'parent_id, :class_name => 'Letter', :dependent => :destroy end

But I would recommend taking a look at the acts_as_tree and acts_as_nested_set plugins and see if they might provide what you are looking for. acts_as_tree provides the parent and children associations like I listed above. acts_as_nested set allows you to retrieve all children in a single query. (http://dev.rubyonrails.com/ svn/rails/plugins/)

Aaron

Theo Graham-brown wrote:

Okay,

I have the site running (http://www.londonprogressivejournal.com) and if you look you can 'respond' to any given article which leads to you submitting a 'letter' object to the system.

At a later date we'll be publishing these.

Articles can of course have many letters. Letters only have one article.

However, people will be able to respond to a published letter just as they will to an article.

So a Letter can have many letters (those that are responses to it)...but it also only has one letter if it is itself a response to an existing letter.

My Letter model has both an article_id and a letter_id but my issue is how to show Ruby that model? I have said 'has many letters' but now of course I can't refer to letter.letter.id to find out which letter this one might be a response to.

Does anyone know how to deal with this sort of self-referential architecture in ruby?

Cheers Theo

Let me restate your problem from the Letter's point of view. A Letter belongs_to a parent (either a Article or another Letter). It also has_many responses (always other letters). I would build you letter class like this.

class Letter < ActiveRecord::Base   belongs_to :parent, :polymorphic=>true   has_many :responses, :class_name =>'Letter', :as=>:parent end

Same thing for Article

class Article < ActiveRecord::Base   has_many :letters, :as=>:parent end

As a side benefit, you can attach a letter to anything else on your site. You may also want to add validation on the belongs_to association to ensure that it only contains the classes you wish to attach letters to.