About nested resources


#1

Hi all,

I have several resources:

map.resources :articles, :has_many => [:comments]
map.resources :movies, :has_many => [:comments]
map.resources :photos, :has_many => [:comments]

all of them have a nested resource named comments, new comments are
able to be created by POST to URLs like article_comments_url. My problem
is, when I’m in the comments_controller, how can I know which resource
this comment belongs to? By reading the params? I think this is not
decent, are there any better ways? Thanks in advance!

Cheers,
Difei


#2

Difei,

If a comment only belongs to either an article, movie or a photo
(never more than one) you could add methods in the model to determine
which it is for.

For example:

class Comment

def article_comment?
!article_id.nil?
end
end

@comment.article_comment? will return true if this is a comment for an
article and false if not.

You could render your view accordingly for each type of comment.

Hope that helps?

On Feb 21, 5:53 am, Difei Z. removed_email_address@domain.invalid


#3

Gavin wrote:

Difei,

If a comment only belongs to either an article, movie or a photo
(never more than one) you could add methods in the model to determine
which it is for.

For example:

class Comment

def article_comment?
!article_id.nil?
end
end

@comment.article_comment? will return true if this is a comment for an
article and false if not.

You could render your view accordingly for each type of comment.

Hope that helps?

Hi Garvin, but your way is to decide the father of an existed comment.
if I just received POST to /articles/:article_id/comments/:comment_id,
and I have a:
@comment = Comment.new(params[:comment]), how could I tell this @comment
is for article but not photo? By test params?

Thanks.

On Feb 21, 5:53�am, Difei Z. removed_email_address@domain.invalid


#4

That seems like a fine solution.

what about just creating three different types of comments,
article_comment, movie_comment, photo_comment?

I’m not necessarily advocating for this, but it’s an option, and it
may be better. That way, you don’t need the functions at all. and it
should help keep your controllers & views simple.

There is in some sense a problem of code duplication between the three
comment resources, but you may be able to DRY this up with helper
methods.

-Gabe


#5

Ah - I think I understand now.

I would add a column to the comments table called ‘kind’ (as in, ‘kind
of comment’)

The column should be an integer column with limit 1.

Then assign a different integer value to determine what kind of
comment it is.

i.e.,
1 = article
2 = photo
3 = movie

When you creating a new comment, simply check the value of this
integer and redirect accordingly.

Does that help?

On Feb 22, 3:27 pm, Difei Z. removed_email_address@domain.invalid


#6

Hypothetically, if one were to create three different types of comment
would you just create a Comment model and then three other models that
were subclasses?

I’ve never played with subclasses in a rails app (other than the ones
specified by rails) so I’m curious as to which whether this would be
the way to do it?

Gav


#7

Hi all,

Since my commentable resources are not too many, I decided to do
something like this in the comment controller:

before_filter: find_resource

private
def find_resource
if params[:article_id]
@resource = Article.find(params[:article_id])
elsif params[:photo_id]
@resource = Photo.find(params[:article_id])
end
end

Thank y’all,
Difei