views:

63

answers:

2

Here is the scenario, Articles have many Comments Users can write many Comments for many Articles

The comments table contains both

user_id
article_id

as foreign keys

My models are set up like so

class User < ActiveRecord::Base
  has_many :comments
  has_many :articles, :through => :comments

class Article < ActiveRecord::Base
  has_many :comments
  has_many :users, :through => :comments

class Comment < ActiveRecord::Base
  belongs_to :users
  belongs_to :articles

My routes.rb has the following code

  map.resources :articles, :has_many => :comments  
  map.resources :users, :has_many => :comments

which produces the following routes

new_article_comment
edit_article_comment
new_user_comment
edit_user_comment
etc...

This is not what I want (atleast not what I think I want), since comments must always be related to users and article, how can I get a route like so

new_user_article_comment
edit_user_article_comment

Then I could just do

new_user_article_comment_path([@user, @article])

to create a new comment

A: 

You could probably do this using nested routes. This article has a good example of how to do that:

http://weblog.jamisbuck.org/2007/2/5/nesting-resources

Note that the article is basically saying "don't do it":

"Rule of thumb: resources should never be nested more than 1 level deep. A collection may need to be scoped by its parent, but a specific member can always be accessed directly by an id, and shouldn’t need scoping (unless the id is not unique, for some reason)."

However, the above quote doesn't really apply to your action, as well as other cases where the unique id is not (yet) available, since you don't yet have a unique id for the comment, and the user and article ids are absolutely necessary. A comment on that same page offers this qualification:

Thijs van der Vossen said... "We’ve invented a second rule of thumb; resources should only be nested for actions that really need the parent id (like ‘index’, ‘new’, and ‘create’). We started using this for an application with a data model that’s almost entirely hierarchical except where it’s not and it seems to work very nicely. Why keep the parent resource in the url when the structure is not strictly hierarchical?"

Steven
My comments table does have a unique identifier, its id column that rails creates automatically for every table.
Maulin
That's right, but at the point when you're creating a new comment by calling new_user_article_comment_path([@user, @article]) you won't (yet) have a unique id.
Steven
I see, I dont understand how nesting will work in my situation.nesting users > articles > comments doesnt work, because it means that I must have a user_id foreign key in the article table.
Maulin
A: 

You have created a circular database schema. Not really recommended.

The data model should look like this:

class User < ActiveRecord::Base
  has_many :comments

class Article < ActiveRecord::Base
  has_many :comments

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :article

And the basic routing:

map.resources :articles do |articles|
  articles.resources :comments
end

And then decide what else do you need to make it fit your requirements.

Paweł Gościcki