2011-07-21 7 views
5

Actualmente tengo un controlador de comentarios que tiene el método vote_up y vote_down así es como mi voto_actualmente funciona.¿Cómo implementar un voto por usuario por comentario?

Mi modelo de comentario tiene una descripción y un campo de conteo.

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 

Esto permite múltiples subidas y bajadas de votos. ¿Cómo lo diseñaría para que un usuario solo pueda votar una vez por comentario, pero de alguna manera realizar un seguimiento si votó a favor o en contra, de modo que tenga la capacidad de cambiar su voto si así lo desea también?

+0

tenga en cuenta también que hay muchos resultados encontrados al buscar 'un voto por usuario' en SO – KevinDTimm

+0

Necesitará otro modelo para rastrear los votos. Puede usar restricciones de exclusividad para permitir solo un voto por usuario, que es exactamente lo que hace la respuesta de Mikhailov. –

+0

Estaba leyendo esa respuesta, pero ¿cómo podría hacerlo para que un usuario pueda cambiar su voto más tarde? Digamos desde -1 hasta 1 – Kevin

Respuesta

3

Se podría hacer algo como esto. Prohíbe votos idénticos pero permite cambiar el voto a lo contrario (es un sistema de aprobación/aprobación).

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 

la migración:

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 

Alternativamente, se puede utilizar una gema llamada thumbs_up o cualquier otro.

+0

Gracias por esto utilicé este método con algunas otras modificaciones que obtuve de @mikhailov y lo tengo para finalmente funcionar – Kevin

1

tal vez podría agregar una validación de su modelo para asegurarse de que el recuento es numéricamente igual o inferior a 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

Sí, pensé que necesitaba otro modelo para los votos, pero ¿cómo implemento una manera de permitir que un usuario cambie su voto más tarde? – Kevin

+0

** update ** action encontrará el voto por respuesta y las identificaciones de usuario, luego actualice su voto – Anatoly

+0

Necesita explotar esto un poco: tenga un archivo de migración y modelo para sus votos. Atributos: [id], user_id: integer, comment_id: integer, is_up: boolean; luego puede tener un alcance (o función de clase) en su modelo de Voto para devolver el número de votos hacia arriba o hacia abajo para un comentario dado. Más importante aún: puede hacer un seguimiento de qué usuario votó qué comentario, y permitir que los usuarios cambien sus votos. – emrass

Cuestiones relacionadas