2010-09-03 5 views
3

En ce moment, je suis en train de construire une application de médias sociaux sur Ruby on Rails, j'ai mis en place un système de vote en 5 points. Où vous pouvez voter les nouvelles affichées sur le site de 1-5, ce que je voudrais savoir, Quelle est la meilleure approche pour gérer les mises à jour sur le système de vote.Mise à jour du vote sur Ruby on Rails

Dans l'exemple. Si un utilisateur a déjà voté dans un article je voudrais ramener le score qu'il a donné dans l'article et verrouiller le vote (puisque je n'autorise que 1 vote par utilisateur et je permets de changer de vote à tout moment), mais si il n'a pas je vais élever l'article avec le le vote sur 0.

Je sais un moyen d'accomplir cela, je pourrais le faire dans la vue, et vérifier si l'utilisateur actuel a déjà voté sur cet article Je les enverrais à la vue EDIT sinon à la vue SHOW. (Je pense)

De toute façon, quelle serait l'approche "correcte" pour le faire?

EDIT: J'ai oublié de dire que la zone de liste déroulante de vote c'est partiel que je suis en train de rendre. Suis-je suppose de mettre à jour le partiel en quelque sorte?

EDIT2:

class Article < ActiveRecord::Base 

    has_many :votes 
    belongs_to :user 

    named_scope :voted_by, lambda {|user| {:joins => :votes, :conditions => ["votes.user_id = ?", user]} } 
end 

class User < ActiveRecord::Base 
    has_many :articles 
    has_many :votes, :dependent => :destroy 

    def can_vote_on?(article) 
    Article.voted_by(current_user).include?(article) #Article.voted_by(@user).include?(article) 
    end 

end 
+1

Quoi que vous fassiez dans la vue, ne négligez pas les chèques dans le contrôleur (par exemple, si l'utilisateur est en droit de vote , ignore s'il a déjà voté). Il est facile pour l'utilisateur d'obtenir ou de publier ce qu'il veut, peu importe les idées que le HTML a à son sujet. –

+0

Oui ... J'ai actuellement les "vérifications" sur le contrôleur (et la base de données) appliquées en ce moment, je cherche juste la manière "efficace" de le faire réellement dans la vue je suppose. – Gotjosh

Répondre

1

Créer une méthode dans le modèle de l'utilisateur qui répond true si l'utilisateur peut voter sur un article:

class User < ActiveRecord::Base 

... 

def can_vote_on?(article) 
    articles_voted_on.include?(article) # left as an exercise for the reader... 
end 

end 

Dans la vue, rendre un formulaire si la l'utilisateur peut modifier, sinon afficher une vue normale:

<% if @user.can_vote_on?(@article) %> 
    <%= render :partial => "vote_form" %> 
<% else %> 
    <%= render :partial => "vote_display" %> 
<% end %> 

Ou vous pouvez gérer le tout dans le contrôleur, et rendre des modèles distincts pour la version du formulaire et la version normale. La meilleure approche dépend des spécificités de votre situation.

EDIT2

Comme vous le découvriez, current_user ne fonctionne pas dans le modèle. Cela a du sens, car on peut l'appeler à partir de migrations, de bibliothèques, etc., où il n'y a pas de concept de session.

De toute façon, il n'est pas nécessaire d'accéder à l'utilisateur actuel, puisque votre méthode d'instance est (par définition) appelée sur une instance. Il suffit de se référer à self dans le modèle, et appeler la méthode de la vue sur current_user, qui est une instance de l'utilisateur:

(dans le modèle)

def can_vote_on?(article) 
    Article.voted_by(self).include?(article) 
    end 

(dans la vue)

<% if current_user.can_vote_on?(@article) %> 

Ou vous pouvez remplacer @user par current_user si le contrôleur l'affecte.

Une dernière chose, je pense que votre champ nommé devrait utiliser user.id, comme ceci:

named_scope :voted_by, lambda {|user| {:joins => :votes, :conditions => ["votes.user_id = ?", user.id]} } 
+0

où devrais-je définir cette méthode? articles_voted_on – Gotjosh

+0

Vous pouvez créer une étendue nommée dans le modèle User pour récupérer les articles votés. – zetetic

+0

Etes-vous certain de devoir créer la portée nommée sur le modèle Utilisateurs? Cela fait maintenant quelques jours que je me bats avec ça et je n'arrive pas à penser comment je peux retourner une liste d'articles sur lesquels l'utilisateur actuel a voté, mais j'ai réussi à le faire facilement à partir du modèle Articles. J'ai modifié mon message et ajouté la méthode. Peut-être pourriez-vous m'éclairer un peu plus. – Gotjosh