开发者

Creating forms for polymorphic associations in Rails

I have a couple classes that can each have comments:

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

class Actor < Activ开发者_如何学运维eRecord::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.)


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜