Создание форм для полиморфных ассоциаций в Rails - PullRequest
14 голосов
/ 20 сентября 2010

У меня есть пара классов, каждый из которых может иметь комментарии:

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

Как создать форму для нового комментария к фильму?Я добавил

resources :movies do
    resources :comments
end

в мой rout.rb и попробовал new_movie_comment_path (@movie), но это дает мне форму, содержащую commentable_id и commentable_type [которую я хочу заполнить автоматически, а не вводить пользователем напрямую].Я также попытался создать форму самостоятельно:

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

(где «текст» - это поле в таблице комментариев), но это тоже не работает.

Я не совсем уверенкак связать комментарий с фильмом вообще.Например,

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

не создает комментарий к фильму с идентификатором 1. (Movie.find (1) .comments возвращает пустой массив.)

Ответы [ 2 ]

7 голосов
/ 20 сентября 2010

Поскольку вы создали полиморфную ассоциацию в своей модели, вам больше не нужно беспокоиться об этом в представлении.Вам просто нужно сделать это в вашем контроллере комментариев.

@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.
3 голосов
/ 20 сентября 2010

Вы должны быть более информативным, чем "... но это тоже не работает", но общая идея такова:

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

Более типично:

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

Важно то, что вы сначала нашли @movie и через него создали связанные с ним объекты. Таким образом, вам не придется беспокоиться о Commentable или типах или о чем-либо.

...