Question

I have the following code in my Rails 3 applications controller:

  def like
    @suggestion = Suggestion.find(params[:id])
    @suggestion.voteip = request.env['REMOTE_ADDR']
    @suggestion.update_attribute(:votes, @suggestion.votes + 1)
    redirect_to suggestions_url
  end

  def dislike
    @suggestion = Suggestion.find(params[:id])
    @suggestion.voteip = request.env['REMOTE_ADDR']
    @suggestion.update_attribute(:votes, @suggestion.votes - 1)
    redirect_to suggestions_url
  end

As you can see the code increments/decrements the vote integer by 1 and adds the users IP address to the column called voteip.

What I am trying to achieve is a simple block on votes from the same IP twice in a row. So if for example my IP was 123.123.123.123 and I voted on something, I couldn't then vote on the same suggestion again (either up or down) from the same IP address.

This is a really simple and nowhere near foolproof method of rate-limiting votes. Although, in the environment it's going to be used in it's almost perfect!

Once I've got this working I'm planning on adding another column for the vote timestamp, then I can do things like only allowing voting from the same IP after 5 minutes have passed.

Any advice would be appreciated!

Was it helpful?

Solution

One way to do it is to find the last vote which has the ip of the REMOTE_ADDR.

Add this in your controller.

def like
  @suggestion = Suggestion.find(params[:id])
  remote_addr = request.env['REMOTE_ADDR']

  @last_vote = Suggestion.find_ip(remote_addr).last

  if @last_vote.created_at < 2.minutes.ago
    render :text => "get lost"
  else
    @suggestion.voteip = remote_addr
    @suggestion.update_attribute(:votes, @suggestion.votes + 1)
    redirect_to suggestions_url
  end
end

And add this in your Suggestion model

def self.find_ip(ip)
  where('voteip = ?', "#{ip}")
end

I created a quick app and tested it so it does work. Of course you can change the 2.minutes.ago to whatever time frame you want.

Hope this helps!

OTHER TIPS

A vote is really a separate resource. Especially if you want to implement a more robust system in the future you'll want your votes to be a separate table, through a has_many relationship. This way it is super easy to compare when the last vote by a particular ip occurred (used as an index, or if the user is authenticated possibly the user_id). Also this allows you to create voting histories for IP's/Users.

User/ip has many suggestions which has many votes. Just my two cents.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top