简体   繁体   中英

Rails `link_to` method posting multiple times

[see later answer for more]

I think this is just a simple rails question, and mostly on how i've named my models and reference them in my view. So a little background, I'm using the vote_fu plugin, which I think is great, however I'm having a hard time getting the voting to work from a link as follows:

<%= link_to "vote for", current_user.vote_for(answer) %>

Where current_user is a helper and returns the current user that is logged in making this request, the issue is likely in the way I state answer which belongs to my question model, any help is really appreciated , even if you just help me down the right path!

oh! also it works in console... so if I do:

user = User.find(1)
user.vote_for(Question.last)

It works as expected.

The example, which is pretty old, has this in the view:

<%= link_to "Vote Up", :url => current_user.vote_for(answer), :method => :post %>

But this makes the URL have the vote method in the query string... he is using rjs, and I'd prefer to use jquery, not sure how to go about my next step in getting this to work and not vote for all the answers on the page?

A clarification of " vote_for belongs in your controller":

You have:

<%= link_to "Vote Up", current_user.vote_for(answer) %>

What you really want is:

<%= link_to "Vote Up", :controller => 'my_controller', :action => 'vote', :id => answer %>

The current_user.vote_for method is a method on the server. If you call that method in your view (.rhtml file), the vote will happen when the page is rendered, not when the user clicks the link. Instead, create a 'vote' method on an appropriate controller (I called it my_controller here, make it whatever you want). The vote method then looks like the vote_fu example. The link_to creates a hyperlink to the voting action.

If you're trying to do this via ajax, replace link_to with link_to_remote .

<%= link_to_remote "Vote Up", :url => { :controller => 'my_controller', :action => 'vote', :id => answer } %>

If your views/my_controller/vote template file is '.rjs', the javascript in that file will be executed when the result of the method returns to the page. If it is '.rhtml', you should look into the helpers for link_to_remote for easily updating a div on the page with the contains of the result of the method ( http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html#M001645 - you want the :update option )

current_user.vote_for(answer) will call that method right away. Just because it's in :url doesn't mean it gets any special treatment. It'll be executed just like any other ruby method.

You probably want to do something like this.

// view
<%= link_to "Vote up", :url => vote_up_answer_path(answer), :method => "post" %>

// controller
class AnswersController < ApplicationController
  def vote_up
    answer = Answer.find(params[:id])
    current_user.vote_up(answer)
    redirect_to :back
  end
end

// routes
map.resources :answers, :member => {:vote_up => :post, :vote_down => :post}

Blah! I solved the first part of my question... well... maybe, it seems my solution isn't very restful, here is what I did:

<%= link_to "Vote Up", :url => current_user.vote_for(answer), :method => :post %>

So the weird thing here is that it works, but every time I reload the page it adds a vote up to all the users with an answer (or comments as most blogs would be concerned), it also makes the url localhost/questions/65?method=post&url=true , I'm not sure what my next plan of action here is.


After a little more investigation, the example the vote_fu example app has this in the controller's create action, but I don't even have a controller for my vote model and the votes are still made, any idea?

def create
@quote = Quote.find(params[:quote_id])

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM