Rails:c.id在comment.each do | c.id |中提交nil块

时间:2014-11-02 23:09:12

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

我试图为用户实施评论系统,其中每个评论都可以被投票。我有一个模型UpVote多态地属于多个模型,包括评论,而每个用户has_many评论。

UpVote模型:

class UpVote < ActiveRecord::Base
  belongs_to :voteable, polymorphic: true
end

评论模型:

class Comment < ActiveRecord::Base
  belongs_to :user
  has_many :up_votes, as: :voteable
end

用户模型:

class User < ActiveRecord::Base
  has_many :comments
  has_many :up_votes, as: :voteable
end

用户显示:我在错误行周围添加了星号。

<% @user.comments.each do |c| %>
  <%= c.text %>
  <%= c.username %>
  <%= c.id %>
  ***<%= link_to "upvote", upvote_comment_path(c.id), method: :post, :class => "btn btn-small" %>***
<% end %>

评论控制器:

def upvote
  @comment = Comment.find(params[:id])
  UpVote.create!(voteable_id: params[:id], voteable_type: 'Comment')
  redirect_to root_path
end

路线:

post 'comments/:id/upvote' => 'comments#upvote', as: 'upvote_comment'

但是当我在用户页面上为评论提交UpVote时,我收到以下错误:

ActionController::UrlGenerationError in Users#show
No route matches {:action=>"upvote", :controller=>"comments", :id=>nil} missing required keys: [:id]

看起来link_to并不接受c.id,这很奇怪,因为c.id本身就会打印@ comment.id。我做错了什么?

BOUNTY MESSAGE中的错误:我的意思是&#34; @ comment.id&#34;,而不是&#34; @ comment.up_vote.count&#34;在赏金信息中,但它没有出现我可以编辑它。

3 个答案:

答案 0 :(得分:1)

我怀疑您在@user.comments中有id nil的评论,因为它尚未保留。如果您使用@user.comments.new@user.comments.build设置新评论,则可能会发生这种情况。这两种方法都会将空白注释添加到@user.comments数组。

您可以通过多种方式避免显示未保留的评论(see this question)。我认为最好的解决方案是避免在关联上使用buildnew。相反,如果您需要显示新评论(例如在表单中),则需要Comment.new而不是@user.comments.build@user.comments.new

答案 1 :(得分:0)

解决问题的正确方法是修改routes.rb,将操作upvote更改为on: :member

  resources :comments do
    post :upvote, on: :member
  end

OR

post 'comments/:id/upvote' => 'comments#upvote', as: 'upvote_comment'

答案 2 :(得分:0)

可能发生的事情是你创造了一条静态而非足智多谋的路线。在这种情况下,您可能必须在link_to

中明确指定id
<%= link_to "upvote", upvote_comment_path(:id => c.id), method: :post, :class => "btn btn-small" %>

您可以通过创建一个足智多谋的路线来避免这种额外的标记,就像您在示例中所尝试的那样

resources :comments do
 member do
   post 'upvote'
 end
end

不确定为什么&#34; on :: member&#34;虽然语法在功能上等同于块语法,但它并不适合您。我认为问题可能是您使用符号而不是字符串指定操作(upvote)。

祝你好运