2010-02-22 15 views
3

J'ai essayé de mettre en place un système de vote robuste dans Rails depuis un certain temps mais j'ai eu du mal à le faire. Au départ, j'ai construit mon propre système de vote, mais c'était simpliste. En résumé, il suffit d'incrémenter une colonne votes_count dans le modèle Answer en utilisant le cache du compteur. Cela a fonctionné très bien pour moi pendant un moment jusqu'à ce que je découvre vote_fu et ai réalisé combien plus robuste mon système de vote pourrait être. Je l'ai immédiatement installé et j'ai passé tout le week-end à déchirer mon application en essayant de le faire fonctionner.Implémenter vote_fu dans l'application rails (ou alternatives)

J'ai trouvé quelques autres questions ici sur Stack Overflow liées à ce plugin, mais aucun d'entre eux n'a trouvé de solution finale. Voici mon code:

answers_controller.rb:

def vote_up 
    answer = Answer.find(params[:id]) 
    current_user.vote_up(answer), :voter_id => current_user.id 
    redirect_to :back 
end 

votes_controller.rb:

def create 
    @quote = Answer.find(params[:answer_id]) 

    respond_to do |format| 
    if current_user.vote(@answer, params[:vote]) 
     format.rjs { render :action => "create", :vote => @vote } 
     format.html { redirect_to root_url } 
    else 
     format.rjs { render :action => "error" } 
     format.html { render :action => "new" } 
     format.xml { render :xml => @vote.errors, :status => :unprocessable_entity } 
    end 
    end 
end 

answer.html.erb: (deux méthodes différentes ici, ni de ces travaux)

<span id="vote_form" style="float: right;"> 
    <%= link_to "Vote up", :url => vote_up_answer_path(answer) %> 
/
    <%= link_to_remote "Down", : 
    url => user_answer_votes_path(answer.user, answer, :vote => :false, :format => :rjs), :method => :post 
    %> 
</span> 

<span id="<%= answer.id %>_vote_score" class="vote_score"> 
    <%= answer.votes_for - answer.votes_against %> 
</span> 

routes.rb:

map.resources :users, :member => { :suspend => :put, :unsuspend => :put, :purge => :delete } do |user| 
    user.resources :votes 
    user.resources :answers do |answer| 
    answer.resources :votes 
    end 
end 
map.resources :answers, :has_many => :votes, :member => {:vote_up => :post, :vote_down => :post} 

J'utilise Rails 2.3.5.

Quelqu'un a-t-il des suggestions? Devrais-je revenir à mon ancien système de vote fait à la main? Y at-il un autre plugin de vote ou une méthode dont je n'ai pas entendu parler?

+0

Votez_fu est super. Qu'est-ce qui ne fonctionne pas en particulier? – Jonathan

+0

ça me semble super aussi! C'est pourquoi je veux vraiment le faire fonctionner! Il semble que mon interface link_to ne fonctionne pas ... il n'ajoute simplement aucun vote quand je clique. En outre, dans la console lorsque je tente u = User.first a = Answer.last u.votes_for (a) je reçois une erreur comme: "attribut inconnu: électeur" ... je suis Je ne sais pas comment corriger cela. – goddamnyouryan

Répondre

1

Je pense que la première étape sera de le faire fonctionner à travers la console. De la dernière erreur dans votre commentaire, il semble que vos modèles ne soient pas correctement configurés. Dans votre modèle User vous devez disposer des éléments suivants:

#In User.rb 
acts_as_voter 

#In Answer 
acts_as_votable 

Aussi, assurez-vous que vous avez appliqué rake:migrate à votre base de données, essayez ceci dans la console:

u = User.first 
a = Answer.last 
u.votes_for(a) 

Quand je dans le passé Je voudrais avoir une action de contrôleur qui ressemblait à ce qui suit:

def vote 
    @question = Question.find(params[:id]) 
    if params[:vote] == 'up'  
    current_user.vote_for(@question) 
    elsif params[:vote] == 'down'  
    current_user.vote_against(@question) 
    end 
    redirect_to @question 
end 
0

La réponse par jt m'a aidé à le faire fonctionner. Mon contrôleur n'avait pas la méthode vote_for sortie de la boîte. Je pense qu'ils devraient ajouter cela à la documentation.

def vote 
    @question = Question.find(params[:id]) 
    if params[:vote] == 'up'  
     current_user.vote_for(@question) 
    elsif params[:vote] == 'down'  
     current_user.vote_against(@question) 
    end 
    redirect_to @question 
    end