私はこのステートメントを使おうとしています:
@vote = Vote.where(:resource_id => params[:id], :user_id => current_user.id).first_or_create(:value => 1)
これは賛成票または反対票用です。行がDBに存在しない場合は、それを作成する必要があります(その投稿に投票したことがない場合)。それ以外の場合は、値を-1,0,1に変更する必要があります。
もう一度賛成票をクリックした場合は、投票を「元に戻す」必要があり、行「value」を1ではなく0に設定する必要があります。反対票でも同じことが起こりますが、これは現在の賛成票機能のみです。
Railsでこのステートメントをデバッグするのに問題があります。基本的に、保存されたレコードか作成されたレコードかを区別する必要があります。私が置く場合:
@vote = Vote.where(:resource_id => 25, :user_id => 1)
@vote.exists?
私は得るtrue
しかし、私がこれを置くと..(そしてレコードが存在する場合、それはちょうど上で機能しました)。
@vote = Vote.where(:resource_id => 25, :user_id => 1).first_or_create(:value => 1)
@vote.exists?
取得します...NoMethodError:未定義のメソッドが「存在しますか?」にとって #
2つのオブジェクトのクラスを見ると、1つは「投票」で、もう1つは「ActiveRecord::Relation」であることがわかります。
私の最終的な目標は、これを何らかの形でリファクタリングすることです(ほとんどの場合、投票値がすでに1であるかどうかをチェックする部分です。ゼロに設定する(投票を取り消す)場合は、1に設定します)。
これは、first_or_createでリファクタリングを開始する前のコードです。その長くて醜い。
if @vote.exists?
# Check if they have already voted
if @vote.first.value == 1
@vote.first.value = 0
else
@vote.first.value = 1
end
flash[:notice] = "previous vote modified"
@vote.first.save
else
# Create a new Vote instance, save it
@vote = Vote.new(:resource_id => params[:id], :user_id => current_user.id, :value => 1)
if @vote.valid?
@vote.save
flash[:notice] = "New vote added"
else
@vote.save
flash[:notice] = (@vote.errors.full_messages).to_s
end
end