0

私のコードの基本的な概要は次のとおりです。

  1. ユーザーが特定の「レポート」に関連付けられた「投票」オブジェクトを持っているかどうかを確認します

  2. そのような投票オブジェクトがない場合は、作成します。

  3. 値を割り当てます (賛成票と反対票)

  4. そのような投票オブジェクトがある場合は、既存の投票の値を変更します。

ただし、ここに問題があります...データベースに (明らかに) 存在する場合でも、プログラムは投票オブジェクトを決して見つけません!

私のコードは次のようになります。

    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
4

1 に答える 1

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

重要: そしてもう 1 つ。このメソッドのほとんどをレポート モデルに移植する必要があります。

于 2012-04-19T04:23:21.877 に答える