我的代码的基本概要是:
检查用户是否有与特定“报告”关联的“投票”对象
如果没有这样的投票对象,则创建一个。
为其指定一个值(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 =&gt;: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
答案 0 :(得分:0)
检查Dynamic attribute-based finders。您应该可以执行以下操作:(未经测试的代码)
def vote_up # voting code
current_report = Report.find(params[:id])
@report = current_report
# gets the vote or initialize a new one for that user_id
@vote = current_report.votes.find_or_initialize_by_user_id(current_user.id)
if !@vote.saved?
@vote.votable_type = 'Report'
@vote.value = 0
# current_report.votes << @vote #not sure if it's necessary
# current_report.save #not sure if it's necessary
@report.upvotes += 1
@vote.value = 1
elsif @vote.value == -1
@report.upvotes += 1
@report.downvotes -= 1
@vote.value = 1
end
@vote.save
@report.save
redirect_to(report_path(@report))
end
重要提示:还有一件事。您应该将此方法的大部分内容移植到您的报表模型中,这显然是一件商业事情,所以应该去哪里!