views:

106

answers:

2

I have a couple classes that can each have comments:

class Movie < ActiveRecord::Base
    has_many :comments, :as => :commentable
end

class Actor < ActiveRecord::Base
    has_many :comments, :as => :commentable
end

class Comment < ActiveRecord::Base
    belongs_to :commentable, :polymorphic => true
end

How do I create a form for a new movie-comment? I added

resources :movies do
    resources :comments
end

to my routes.rb, and tried new_movie_comment_path(@movie), but this gives me a form containing commentable_id and commentable_type [which I want to be populated automatically, not entered by the user directly]. I also tried creating the form myself:

form_for [@movie, Comment.new] do |f|
    f.text_field :text
    f.submit
end

(where "text" is a field in the Comment table) but this doesn't work either.

I'm not actually sure how to associate a comment with a movie at all. For example,

c = Comment.create(:text => "This is a comment.", :commentable_id => 1, :commentable_type => "movie") 

doesn't seem to create a comment associated to the movie with id 1. (Movie.find(1).comments returns an empty array.)

A: 

You're going to have to be more descriptive than "...but this doesn't work either," but the general idea is:

@movie.comments.create( :text => params[:movie][:comment][:text] )

More typically:

@movie.comments.create( params[:comment] ) # or params[:movie][:comment]

The important thing is that you find @movie first and create your associated objects through it. That way you won't have to worry about Commentable or types or anything.

Eric Hill
+1  A: 

As you have created the polymorphic association in your model, you need not worry about that anymore in the view. You just need to do this in your Comments controller.

@movie = Movie.find(id) # Find the movie with which you want to associate the comment
@comment = @movie.comments.create(:text => "This is a comment") # you can also use build
# instead of create like @comment = @movie.comments.create(:text => "This is a comment")
# and then @comment.save
# The above line will build your new comment through the movie which you will be having in
# @movie.
# Also this line will automatically save fill the commentable_id as the id of movie and 
# the commentable_type as Movie.
Rohit
How do I build a form to enter the comment? I don't think I want "form_for @movie.comments.create do |f| f.text_field :text; f.submit end", because I only want to create the comment if it's actually submitted. And for some reason, @movie.comments.build doesn't seem to associate the comment with the movie.
grautur
You can add a button 'Add Comment' on Movie show page that will redirect you to movie edit page with comments field added to it. This can be done as below :
Rohit
<% form_for(@movie) do |f| %> <%= f.error_messages %> <p> <%= f.label :name %><br /> <%= f.text_field :name %> </p> <% f.fields_for :comments do |v| %> <p> <%= v.label :comment %> <%= v.text_area :comment %> </p> <% end %><% end %>
Rohit