我的代码的基本大纲是这样的:
检查用户是否有与特定“报告”关联的“投票”对象
如果没有这样的投票对象,则创建一个。
给它一个值(upvote vs. downvote)
如果存在这样的投票对象,则更改现有投票的值。
但问题是……即使它(显然)存在于数据库中,程序也永远不会找到投票对象!
我的代码如下所示:
def vote_up # voting code
@was_new = false
current_report = Report.find(params[:id])
@report = current_report
begin
@vote = current_report.votes.find_by_user_id(current_user.id) #<<---HERE IS THE BUG!!
rescue
@was_new = true
@vote = Vote.create(:user_id => current_user.id, :votable_type => 'Report', :value => 0) # default vote score of zero
end
current_report.votes << @vote
current_report.save
if @was_new #if the vote was new...
@report.upvotes += 1
@vote.value = 1
elsif !@was_new and @vote.value == -1 #else, if you are changing your vote...
@report.upvotes += 1
@report.downvotes -= 1
@vote.value = 1
end
@vote.save
@report.save
redirect_to(report_path(@report))
end
我收到的错误是这样的:
SQLite3::SQLException: no such column: votes.votable_id: SELECT "votes".* FROM "votes" WHERE "votes"."votable_id" = 3 AND "votes"."votable_type" = 'Report' AND "votes"."user_id" = 1 LIMIT 1
我觉得解决方案很简单,比如写 @vote = current_report.votes.find(params[:user_id], :as => :user_id) 或类似的东西。
编辑:
我让它工作了。这是工作代码:
def vote_up # voting code
@exists = false
get_vote(1)
if !@exists #if the vote was new...
@report.upvotes += 1
elsif @exists and @vote.value == -1 #else, if you are changing your vote...
@report.upvotes += 1
@report.downvotes -= 1
@vote.value = 1
end
@vote.save
@report.save
redirect_to(report_path(@report))
end
def vote_down
@exists = false
get_vote(-1)
if !@exists # this should handle vote changing
@report.downvotes += 1
elsif @exists and @vote.value == 1
@report.downvotes += 1
@report.upvotes -= 1
@vote.value = -1
end
@vote.save
@report.save
redirect_to(report_path(@report))
end
def get_vote(val) # voting code
current_report = Report.find(params[:id])
@report = current_report
@vote = current_report.votes.find_by_user_id(current_user.id)
unless @vote # create a vote only if it's nil
@vote = Vote.create(:user_id => current_user.id, :votable_id => 3, :votable_type => 'Report', :value => val) # default vote score of zero
current_report.votes << @vote
current_report.save
else #if it's not nil
@exists = true
end
end