所以我真的认为这可以像我们在SO上创建投票系统一样:
def create
@video = Video.find(params[:video_id])
@vote = current_user.video_votes.find_or_create_by_video_id(@video.id)
if @vote.value.nil?
if params[:type] == "up"
@vote.value = 1
else
@vote.value = -1
end
elsif (params[:type] == "up" && @vote.value == 1) || (params[:type] == "down" && @vote.value == -1)
@vote.value = 0
elsif ((params[:type] == "up" && @vote.value == -1) || (params[:type] == "down" && @vote.value == 1)) || (@vote.value == 0)
if params[:type] == "up"
@vote.value = 1
else
@vote.value = -1
end
end
if @vote.save
respond_to do |format|
format.html { redirect_to @video }
format.js
end
else
respond_to do |format|
format.html { redirect_to @video }
format.js {render 'fail_create.js.erb'}
end
end
end
我尝试按照此问题中第一个答案的示例:Why doesn't this Ruby on Rails code work as I intend it to?但是,由于此错误,我的代码不允许我第一次对视频进行投票:
TypeError (nil can't be coerced into Fixnum):
app/models/video_vote.rb:11:in `update_vote_sum'
app/controllers/video_votes_controller.rb:4:in `create
这是我的视频投票模型:
class VideoVote < ActiveRecord::Base
belongs_to :user
belongs_to :video
validates_uniqueness_of :user_id, :scope => :video_id
after_create :update_vote_sum
private
def update_vote_sum
video.update_attributes!(:vote_sum => video.vote_sum + value)
end
end
如果需要,这是我的视频模型中的vote_sum
方法:
def vote_sum
video_votes.sum(:value)
end
答案 0 :(得分:3)
在after_create
中的VideoVote.rb
方法中,您对所有投票进行总结,包括您刚刚创建的具有零值的投票。将after_create
切换为after_update
,或在value
上设置VideoVote
的默认值。
在查看时,如果vote_sum
每次都对所有选票投了sum
,那么您可能甚至不需要after_create
或after_update
方法如果投票有默认值设置。
-
您也可以使用thumbs_up gem替换整个系统,并省去一些麻烦。
答案 1 :(得分:0)
不确定你在这里想做什么。 vote_sum
是一种从我能看到的内容中总结视频投票数的方法,那么为什么要尝试将其更新为属性?它将始终返回视频的正确分数,您不需要手动更新它,因为它不是属性,而是方法的计算结果。