Merit gem - prevent users from voting more than once

73 Views Asked by At

I'm using Merit gem to add reputation system to my application for users that are logged in.

This is an example of how I'm using score to handle voting:

def initialize
  score 5, on: 'posts#upvote', to: :user
  score -5, on: 'posts#downvote', to: :user
  score 1, on: 'posts#upvote', to: :itself
  score -1, on: 'posts#downvote', to: :itself
end

The problem is that with this solution, users can vote on the posts as many times as they want. I would like users to only have a single vote per post. Is there any way to prevent users from voting multiple times?

1

There are 1 best solutions below

0
Michael Gaskill On

You can pass a block to score to determine whether it should allow or not. See Merit: Defining Rules for more information.

This code updates what you had provided to give an example of how you might implement it in your app:

def initialize
  score 5, on: 'posts#upvote', to: :user {|topic| topic.voted?(@user) }
  score -5, on: 'posts#downvote', to: :user {|topic| topic.voted?(@user) }
  score 1, on: 'posts#upvote', to: :itself {|topic| topic.voted?(@user) }
  score -1, on: 'posts#downvote', to: :itself {|topic| topic.voted?(@user) }
end

This assumes that you have (or can build) a method to determine if a user has already voted on a topic. In this case, the method is voted? on the topic that you're allowing votes on.

If you want to allow the user to only vote once, but to reverse a previously cast vote (like SO allows), you can handle that in the block, as well. The complexity of the condition evaluated in the block is entirely up to you.