我试图为用户实施评论系统,其中每个评论都可以被投票。我有一个模型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;在赏金信息中,但它没有出现我可以编辑它。
答案 0 :(得分:1)
我怀疑您在@user.comments
中有id
nil
的评论,因为它尚未保留。如果您使用@user.comments.new
或@user.comments.build
设置新评论,则可能会发生这种情况。这两种方法都会将空白注释添加到@user.comments
数组。
您可以通过多种方式避免显示未保留的评论(see this question)。我认为最好的解决方案是避免在关联上使用build
或new
。相反,如果您需要显示新评论(例如在表单中),则需要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)。
祝你好运