2011-07-21 29 views
5

私は現在、vote_upとvote_downのメソッドを持つコメントコントローラを持っています。これは、私のvote_upが現在どのように動作しているかです。コメント1人につき1人の投票を実装する方法は?

マイコメントモデルには説明とカウントフィールドがあります。

def vote_up 
    @comment = Comment.find(params[:comment_id]) 
    @comment.count += 1 
    if @comment.save 
     flash[:notice] = "Thank you for voting" 
     respond_to do |format| 
     format.html { redirect_to show_question_path(@comment.question) } 
     format.js 
     end 
    else 
     flash[:notice] = "Error Voting Please Try Again" 
     redirect_to show_question_path(@comment.question) 
    end 
    end 

これにより、複数の投票が可能となります。どのようにユーザーがコメントごとに1回だけ投票することができるように、どのように設計するのですか?彼らが投票したかどうかを追跡しているので、投票が必要な場合は投票を変更することができます。

+0

また、多くの結果が見つかりましたので、あなたの投票を追跡する別のモデルが必要になりますSO – KevinDTimm

+0

で '1つの投票ユーザーごと'を検索します。一意性制約を使用すると、1人のユーザーにつき1つの投票しか許可できません。これはまさにMikhailovの答えです。 –

+0

私はその答えを読んでいたが、ユーザーが後で彼の投票を変更できるようにするにはどうすればよいだろうか? 1から1へと言います – Kevin

答えて

3

ていることを確認するためにあなたのモデルに検証を追加することができます。それは同じ票を禁止しますが、反対に投票を変更することができます(それは親指/拇指のシステムです)。

def vote(value, user) # this goes to your model 

    #find vote for this instance by the given user OR create a new one 
    vote = votes.where(:user_id => user).first || votes.build(:user_id => user) 

    if value == :for 
    vote_value = 1 
    elsif value == :against 
    vote_value = -1 
    end 

    if vote.value != vote_value 
    vote.value = vote_value 
    vote.save 
    end 
end 

移行:

def self.up 
    create_table :votes do |t| 
    t.references :comment, :null => false 
    t.references :user, :null => false 
    t.integer :value, :null => false 
    end 
    add_index :votes, :post_id 
    add_index :votes, :user_id 
    add_index :votes, [:post_id, :user_id], :unique => true 
end 

また、あなたがthumbs_upやその他と呼ばれる宝石を使用することができます。

+0

ありがとうございました。私は@mikhailovから得たいくつかの変更を加えてこのメソッドを使用しました。 – Kevin

1

あなたはおそらくカウントはあなたがこのような何かを行うことができますと同じ数値であるか1未満

validates :count, :numericality => { :less_than_or_equal_to => 1 } 
2
class AnswersController < ApplicationsController 
    def vote 
    #params[:answer_id][:vote] 
    #it can be "1" or "-1" 
    @answer = Answer.find(params[:answer_id]) 
    @answer.vote!(params[:answer_id][:vote]) 
    end 

    def show 
    @answer = Answer.find(params[:answer_id]) 
    @answer.votes.total_sum 
    end 

end 

class Answer < ActiveRecord::Base 
    has_many :votes do 
    def total_sum 
     votes.sum(:vote) 
    end 
    end 


    def vote!(t) 
    self.votes.create(:vote => t.to_i) 
    end 

end 

class Vote < ActiveRecord::Base 
    belongs_to :answer 
    belongs_to :user 

    validates_uniqueness_of :user_id, :scope => :answer_id 
end 
+0

そうです、私は投票のために別のモデルが必要だと思いましたが、後でユーザーが投票を変更できるようにする方法をどのように実装しますか? – Kevin

+0

** update **アクションは、回答とユーザーIDで投票を見つけ、次に彼の投票を更新します – Anatoly

+0

あなたは少しこれを爆破する必要があります:あなたの投票のための移行とモデルファイルがあります。属性:[id]、user_id:整数、comment_id:整数、is_up:ブール値。投票モデルでスコープ(またはクラス関数)を使用して、与えられたコメントの上/下投票数を返すことができます。もっと重要なのは、どのユーザーがどのコメントに投票したのかを追跡し、ユーザーが投票を変更できるようにすることです。 – emrass

関連する問題