2011-03-18 7 views
0

J'ai mis en place un système de vote up/down qui se met à jour avec ajax dans mon application Ruby on Rails. Les boutons appellent la méthode create, un vote est inséré dans la base de données et la somme des votes est calculée.Correction mécanisme de vote

Cependant, à partir de maintenant, un utilisateur peut upvote ou downvote autant de fois qu'il le voudrait. Je veux que le vote soit comme ce que nous voyons ici sur StackOverflow, où un utilisateur peut seulement voter une fois ou plus, et les votes peuvent être annulés. Comment puis-je construire la logique pour cela?

Répondre

1

Je recommanderais la gemme acts_as_rateable, c'est ce que j'ai utilisé pour ce genre d'exigence pour plusieurs sites Web. Fait le travail parfaitement.

Si vous préférez l'implémenter vous-même, votre modèle Rating devrait avoir un user_id et être polymorphe de manière à se lier à tous les modèles que vous souhaitez évaluer. Ensuite, vous pouvez simplement coder votre contrôleur AJAX pour rejeter les votes en double. Au début, Javascript qui supprime la fonctionnalité de lien de l'upvote/downvote existante devrait être mis en œuvre pour un bon UX.

+0

En ce moment c'est une ressource indépendante qui a à la fois un ID_vidéo et un id_utilisateur –

+0

Si les vidéos sont la seule chose que vous allez évaluer, alors c'est une bonne approche. Dans ce cas, vous pouvez probablement juste faire @previous_rating = Rating.where (: video_id => params [: video_id],: user_id => current_user.id) .first' et vérifier '@ previous_rating.nil?' Pour vérifier si l'utilisateur a déjà évalué cette vidéo. Si c'est le cas, vérifiez la note entrante et changez-la en version upvote/downvote si elle est différente, ou revenez si c'est la même chose. –

+0

Cela a du sens. Pourquoi devez-vous faire '.first' à la fin de l'appel' where'? L'utilisateur ne devrait-il pas avoir un seul vote de toute façon? –

0

Je pense que vous avez un peu plus de travail à faire. Vous devez ajouter à votre modèle une relation plusieurs à plusieurs entre les questions et les utilisateurs, dans laquelle vous vous rappelez quel utilisateur a voté pour quelle question et de quelle manière (vers le haut ou vers le bas). Après cela, lorsque vous affichez la question à l'écran, vous devez sélectionner dans cette table les votes de l'utilisateur actuel liés à la question affichée. Lorsqu'un utilisateur vote pour une question, vous devez ajouter un enregistrement à la table correspondante. En outre, lors de l'affichage de la question, Si l'utilisateur a upvoted (downvoted), alors vous devez styler le lien upvote (downvote) en conséquence. Et si un utilisateur essaie à nouveau de voter, vous pouvez le vérifier avant d'enregistrer le vote dans la base de données si l'utilisateur a déjà voté. Peut-être que ce n'est pas le moyen le plus rapide de faire ce genre de chose, mais il vous donne le plus de contrôle (vous pouvez ensuite afficher une statistique détaillée sur le style de vote d'un utilisateur, la date et l'heure du vote). casted, vous pouvez imposer une limite au nombre de voix un utilisateur peut lancer par jour et ainsi de suite ...)

+0

J'ai déjà une relation de plusieurs à plusieurs entre les vidéos et les utilisateurs avec video_votes comme ressource indépendante. Merci pour le conseil. –

+0

Ensuite, vous devriez vérifier votre méthode ajax si l'utilisateur a déjà voté avant de persister son vote à la base de données –

+0

ouais, c'est ce que je vais faire. –

0
class Vote < ActiveRecord::Base 
    belongs_to :question 
    belongs_to :user 

    validates_uniqueness_of :user_id, :scope=>question_id  
end 

http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M000086

Votre contrôleur renvoie des erreurs si vous essayez de voter plus d'une fois . Demandez à l'interface utilisateur de supprimer le vote si vous votez pour un vote pour lequel vous avez voté.

+0

Si l'utilisateur fait une deuxième mise à jour, le vote devrait être annulé, donc je ne pense pas que ce soit ce que je cherche. –

+0

Pourquoi autoriser un deuxième vote? –

+0

Plus spécifiquement, votre interface utilisateur devrait envoyer une méthode =>: delete si le vote existe. C'est la façon SO. –