Создание форм для полиморфных ассоциаций в рельсах
У меня есть пара классов, каждый из которых может иметь Комментарии:
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
К моим маршрутам.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. (Кино.найти(1).comments возвращает пустой массив.)
2 ответа:
Поскольку вы создали полиморфную ассоциацию в своей модели, вам больше не нужно беспокоиться об этом в представлении. Вам просто нужно сделать это в вашем контроллере комментариев.
@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.
Вам придется быть более описательным, чем "...но это тоже не работает", но общая идея такова:
@movie.comments.create( :text => params[:movie][:comment][:text] )
Более типично:
Важно то, что вы сначала находите@movie.comments.create( params[:comment] ) # or params[:movie][:comment]
@movie
и создаете связанные с ним объекты. Таким образом, вам не придется беспокоиться оCommentable
или типах или о чем-либо еще.