2013-07-04 5 views
1

J'essaie de mettre en place un système de vote où les votes sont limités par les électeurs adresse_ip.Un vote par adresse IP

J'ai un modèle de message qui a beaucoup de_votes et les votes appartiennent au modèle de poste.

Ma question est de savoir comment et où je définis le "current_user" et comment puis-je l'implémenter dans la vue.

Actuellement je crée votes comme ceci:

<%= link_to(post_votes_path(post), :method => 'post') do %> 
<%= song.votes.size %> 

fonctionne très bien, sauf tout le monde peut voter et je veux arrêter cela. S'il vous plaît je ne cherche pas un bijou que j'essaie juste d'apprendre cette fonctionnalité à partir de zéro.

Vive.

Voici mon Messages code du contrôleur:

def create 
@post = Post.new(params[:post]) 

respond_to do |format| 
    if @post.save 
    format.html { redirect_to root_url, notice: 'Post was successfully created.' } 
    else 
    format.html { render action: "new" } 
    end 
end 
end 

et le code contrôleur de vote pour créer une action:

def create 
@post = Post.find(params[:post_id]) 
@vote = @post.votes.create 
respond_to do |format| 
    format.html { redirect_to root_url } 
    #format.js 
end 
end 
+0

Pouvez-vous également indiquer comment sont stockés vos utilisateurs? – AnkitG

+0

Current Je n'ai pas de table d'utilisateurs, je pense à ajouter un vot_id à la table des votes? – Joshua

+2

Vous devez ajouter une colonne 'voter_ip' dans votre table Vote, et y mettre l'adresse IP de l'électeur: '@ post.votes.create (voter_ip: request.remote_ip)' (la variable 'request' n'est disponible que dans Contrôleurs , quand vous recevez une demande) Et puis faites comme @Gene dit, ajoutez un 'validates: électeur_d'électeur, unicité: vrai' dans votre modèle de vote. – MrYoshiji

Répondre

1

Comme le suggère MrYoshiji, vous devriez ajouter une colonne voter_ip à votre table des votes.

Vous pouvez ajouter cette clause AR where à vos messages/votes contrôleur

if @post.votes.where(voter_ip: request.remote_ip).empty? 
    @post.votes.create(vote: params[:post_vote]) 
end 

Cela testera ce poste a des votes de l'IP en cours. Dans le cas où aucun vote n'est enregistré, un nouveau vote est ajouté avec la valeur param de post_vote

Si vous préférez ajouter une contrainte à votre modèle vote, vous devez effectuer une validation de portée.

validates_uniqueness_of :voter_ip, scope: :post_id 

Lors de l'utilisation du paramètre de portée de la contrainte d'unicité est appliquée à la combinaison de voter_ip et post_id, au lieu de voter_ip seul.

+0

Scoped Validation était ce que je recherchais. Travaillé parfaitement. Merci. – Joshua

+1

dans Rails 4, vous pouvez utiliser la clause where.not. http://blog.remarkablelabs.com/2012/12/not-equal-support-for-active-record-queries-rails-4-countdown-to-2013 – scaryguy

+0

Bravo, je me demande comment je peux appeler quelque chose comme "votez_pour "dans une vue. Par exemple, vérifiez si les utilisateurs actuels ip_ ont voté pour un message. – Joshua

1

Les besoins de table votes dans ip colonne avec une contrainte de validation unique. Ensuite, la sauvegarde du contrôleur échouera si vous essayez d'enregistrer plus d'un vote par IP, que vous pouvez détecter et utiliser pour faire clignoter une erreur. Vous devez poster votre code de contrôleur afin d'obtenir une meilleure réponse.

+0

Édité mon message original avec le code du contrôleur. – Joshua

+0

Je me demandais simplement si les rails détecte automatiquement la colonne ip et l'associe à une adresse IP? – Joshua

+0

@Joshua Non, vous devez les relier entre eux dans votre contrôleur. – tadman