sent-hil
sent-hil

Reputation: 19285

Prevent users from voting multiple times in Rails

I've a simple rating system setup in a blog model. I use a custom method to increase rating, which is integer in blog db.

def increase
  @post = Post.find(params[:id]).increment!(:rating)
  if logged_in?
    current_user.increment!(:votes)
  end
  flash[:notice] = "Thanks for rating"
  redirect_to posts_url
end

Right now, I can vote as many times as I want, which is of course a recipe for disaster. Users can vote multiple times and drive the count way way up.

How do I make it so that the vote submit button go away after submitting it once. I thought of making a separate model for rating and use a custom token, but seems needlessly complicated for a simple app.

Any help?

Senthil

Upvotes: 2

Views: 1005

Answers (2)

Sid
Sid

Reputation: 6264

One way of doing this would be to have your Post model and a RatedPost model. The RatedPost model could contain info like incremented:boolean, decremented:boolean, changed_by:integer (user_id), post_id:integer.

You can then identify if RatedPost.find_by_post_id_and_changed_by(post.id, user.id) returns any records.

You can also identify if the points were incremented or decremented. Thus you can allow a user to change his vote for a certain period of time (say 24 hours).

Upvotes: 1

Veger
Veger

Reputation: 37905

You either need to keep a list with users who votes on a particular subject/post or you need to keep a list attached to each user containing the posts the user voted on. Whether you store the information along with the posts or users is your choice and probably depends on your application requirements.

When displaying the page containing the vote button, you have to check whether the current_user already voted or not. And do not show the button if a vote was cast already. For safety reasons you might want to also check whether an user voted in the code you showed above, in order to prevent voting without using the button.

If you also allow people who are not logged in to vote, you'd need to store their IP address or something.

Upvotes: 1

Related Questions