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.