Само-ссылочная ассоциация имеет ошибку маршрутизации - PullRequest
1 голос
/ 22 октября 2010

Я следую учебнику Райана Бэйта: http://railscasts.com/episodes/163-self-referential-association

Но мои настройки немного отличаются.

Я делаю комментарии, которые ссылаются на себя, так что комментарии можно комментировать.

Форма отображается в виде, но когда я отправляю, я получаю это:

Routing Error

No route matches "/conversations"

И мой URL говорит так: http://localhost:3000/conversations?convo_id=1

модель

#conversation.rb
belongs_to :comment
belongs_to :convo, :class_name => "Comment"

#comment.rb
belongs_to  :post
has_many :conversations
has_many :convos, :through => :conversations

Моя форма:

- for comment in @comments
  .grid_7.post.alpha.omega
    = comment.text
    %br/
    - form_for comment, :url => conversations_path(:convo_id => comment), :method => :post do |f|
      = f.label 'Comment'
      %br/
      = f.text_area :text
      %br/
      = f.submit 'Submit'

Мои разговоры_контроллер:

def create
  @conversation = comment.conversations.build(:convo_id => params[:convo_id])

При создании приложения происходит сбой, так как оно никогда не попадает в часть перенаправления create method.

Ответы [ 2 ]

4 голосов
/ 22 октября 2010

Здесь есть над чем поработать, но хорошая новость в том, что я думаю, что ответ, который вы ищете, проще, чем тот, который у вас уже есть. Если я вас правильно понимаю, вы хотите, чтобы в комментариях было много собственных комментариев. Так работает 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, а сама форма осталась бы прежней.

Надеюсь, это поможет!

0 голосов
/ 22 октября 2010

Приложение выходит из строя раньше, чем вы думаете - оно не находит маршрут к этому действию, поэтому оно вообще не достигает его. В вашем файле rout.rb вам нужно добавить:

# rails 3
resources :conversations

# rails 2
map.resources :conversations

Это должно исправить.

...