Здесь есть над чем поработать, но хорошая новость в том, что я думаю, что ответ, который вы ищете, проще, чем тот, который у вас уже есть. Если я вас правильно понимаю, вы хотите, чтобы в комментариях было много собственных комментариев. Так работает YouTube, позволяя участникам отвечать на существующие комментарии. Для этого вам не нужно реализованное вами решение has_many :through
. Вам не нужен объект разговоров вообще. На комментарий может быть много ответов (дочерних комментариев), но в ответе не может быть более одного родителя.
Ответом для этого является использование полиморфизма, который проще реализовать, чем произносить :). Вы хотите, чтобы ваши комментарии принадлежали либо посту, либо другому комментарию. Полиморфизм позволяет объекту принадлежать одной из многих вещей. На самом деле, комментарии являются наиболее распространенным использованием для этого.
Я рассматриваю полиморфизм на примере адресов в этом сообщении в блоге:
http://kconrails.com/2010/10/19/common-addresses-using-polymorphism-and-nested-attributes-in-rails/
Но я могу показать вам, как это относится к вашему делу более конкретно. Во-первых, полностью удалите модель разговора / контроллер / маршруты. Затем измените таблицу комментариев:
change_table :comments do |t|
t.integer :commentable_id
t.string :commentable_type
t.remove :post_id
end
Нам больше не нужен post_id
, потому что мы собираемся изменить то, как мы связываемся с другими таблицами. Теперь давайте изменим модели:
# app/models/post.rb
has_many :comments, :as => :commentable
# app/models/comment.rb
belongs_to :commentable, :polymorphic => true
has_many :comments, :as => :commentable
Обратите внимание, что мы удалили комментарий, относящийся к сообщению напрямую. Вместо этого он соединяется с полиморфной «комментируемой» ассоциацией. Теперь у вас есть неограниченная глубина комментариев, имеющих комментарии.
Теперь в своем действии Post # show вы захотите создать пустой комментарий примерно так:
get show
@post = Post.find(params[:id])
@comment = @post.comments.build
end
@comment
теперь будут автоматически устанавливать commentable_id
и commentable_type
. Теперь на вашей странице показа, используя erb:
<% form_for @comment do |f| %>
<%= f.hidden_field :commentable_type %>
<%= f.hidden_field :commentable_id %>
/* other fields go here */
<% end %>
Теперь, когда вызывается Comments # create, он работает так, как вы ожидаете, и присоединяется к нужному родителю. В приведенном выше примере был показан комментарий, добавляемый непосредственно к сообщению, но процесс для комментария практически не отличается. В контроллере вы бы позвонили @comment.comments.build
, а сама форма осталась бы прежней.
Надеюсь, это поможет!