2012-04-19 16 views
0

我的代碼的基本輪廓是這樣的:看到數據庫shenanigans:如何讓我的網站「記住」用戶已投票?

  1. 檢查用戶是否有特定的「報告」

  2. 如果不存在這樣的投票對象相關聯的「投票」的對象,然後創建一個。

  3. 給它分配一個值(給予好評與downvote)

  4. 如果有這樣的投票對象,然後改變現有的表決的價值。

雖然這個問題雖然...即使它(顯然)存在於數據庫中的程序永遠不會FINDS投票對象!

我的代碼如下所示:

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 [email protected]_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 [email protected] #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 [email protected] # 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

檢查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 [email protected]? 
    @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 

重要:還有一兩件事。你應該將這種方法的大部分移植到你的報告模型中,這顯然是一件商業事情,所以它應該放在哪裏!

相關問題