自引用关联有路由错误

时间:2010-10-22 15:14:41

标签: ruby-on-rails forms ruby-on-rails-3 model associations

我正在关注Ryan Bate的教程:http://railscasts.com/episodes/163-self-referential-association

但我的设置略有不同。

我正在发表自我引用的评论,以便评论评论。

表单显示在视图中,但是当我提交时,我明白了:

Routing Error

No route matches "/conversations"

我的网址说: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'

我的conversations_controller:

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

应用程序在创建时失败,因为它永远不会进入create method的重定向部分。

2 个答案:

答案 0 :(得分:4)

这里有几件可以解决的问题,但好消息是我认为你所寻找的答案比你已经拥有的答案更简单。如果我理解正确,你想要评论有很多自己的孩子评论。这就是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_idcommentable_type。现在在您的节目页面中,使用erb:

<% form_for @comment do |f| %>
  <%= f.hidden_field :commentable_type %>
  <%= f.hidden_field :commentable_id %>

  /* other fields go here */
<% end %>

现在,当调用#manate时,它会像您期望的那样工作,并附加到正确的父级。上面的示例显示直接添加到帖子的评论,但评论的过程基本相同。在控制器中,您可以调用@comment.comments.build,表单本身也会保持不变。

我希望这有帮助!

答案 1 :(得分:0)

应用程序比你想象的更早失败 - 它没有找到通往该行动的路线,所以它根本没有达到它。在routes.rb文件中,您需要添加:

# rails 3
resources :conversations

# rails 2
map.resources :conversations

这应该解决它。