多态注释路由错误

时间:2014-02-25 21:59:56

标签: ruby-on-rails ruby ruby-on-rails-4

看看我刚问过的这个问题:Comments on multiple models

到目前为止,我已正确设置了所有内容,我的评论表,我的模型和控制器。

但是,我遇到了一些路线错误。

在我的路线档案中:

resources :posts do
    resources :comments do
    member do
      put "like", to: "comments#upvote"
    end
  end

  end

  resources :books do
    resources :comments do
    member do
      put "like", to: "comments#upvote"
    end
  end

  end

我的评论表:

<% form_for [@commentable, Comment.new] do |f| %>
  <p>
   <%= f.text_area :body %>
  </p>
  <p><%= f.submit "Submit" %></p>
<% end %>

这是我得到的错误:

未定义的方法`comments_path'

关于如何让路线运转的任何想法?

编辑:

这就是我在评论控制器中的内容:

def index
  @commentable = find_commentable
  @comments = @commentable.comments
end

def create
  @commentable = find_commentable
  @comment = @commentable.comments.build(params[:comment])
  if @comment.save
    flash[:notice] = "Successfully created comment."
    redirect_to :id => nil
  else
    render :action => 'new'
  end
end

private

def find_commentable
  params.each do |name, value|
    if name =~ /(.+)_id$/
      return $1.classify.constantize.find(value)
    end
  end
  nil
end

2 个答案:

答案 0 :(得分:2)

@Katie,@commentable应该为您呈现评论表单的每个操作加载。我认为你放弃comments#new赞成使用books#showposts#show来呈现表单(这很好),但每次要渲染表单时都需要加载该变量

但是,由于在@commentable中定义books#show变量不是很有表现力(您可能已经定义了@book),所以我建议这样做:

为评论表单创建一个新的部分(如果您还没有):

<% form_for [commentable, Comment.new] do |f| %>
  <p>
    <%= f.text_area :body %>
  </p>
  <p><%= f.submit "Submit" %></p>
<% end %>

注意commentable不是此处的实例变量。渲染局部变量时,您将其定义为局部变量。 books/show.html.erb中的某处:

 <%= render partial: "comments/form", locals: { commentable: @book } %>

显然,在其他视图中,将@book替换为commentable的任何变量。

现在您还有另一个问题,即表单数据不会带有commentable_typecommentable_id属性。您可以通过多种方式将这些内容导入CommentsController;这是一个使用隐藏字段的简单方法:

<% form_for [commentable, Comment.new] do |f| %>
  <%= hidden_field_tag :commentable_type, commentable.class.to_s %>
  <%= hidden_field_tag :commentable_id, commentable.id %>
  <p>
    <%= f.text_area :body %>
  </p>
  <p><%= f.submit "Submit" %></p>
<% end %>

您需要将find_commentable操作更改为更简单的操作:

def find_commentable
  params[:commentable_type].constantize.find(params[:commentable_id])
end

答案 1 :(得分:1)

如果您要在PostsController#show操作下呈现评论表单,那么您需要确保在该操作的某个位置定义了@commentable

# PostsController#show
def show
  @post = Post.find(params[:id])
  @commentable = @post
end

这样,定义了@commentable调用中form_for [@commentable, Comment.new]的使用。