I have a rails app that uses voting. Right now I have it set up so
that you can vote on a word, but it doesn't limit the number of votes.
So someone can vote on the same word more than once.
How do I make it so that you can only vote once on a word. Some
methods I've found online included checking for a unique ip address
but that can bring problems for people at work or places with block ip
addresses.
I was thinking that I would have to using session cookies or something
like that. But I'm new to RoR and don't know where to start.
Here is my current code:
# CONTROLLER
class VotesController < ApplicationController
I think that you want to build in an authentication system first
(restful_authentication) so that you can reliably identify who the user
is. After that it is a simple matter of logging a record in a table
that identifies that a user has voted on a specific word. So always
check beforehand if a user has voted on a word and then disallow
repeated voting.
People move around and identifying a user using just the IP address
alone is not sufficient in my opinion.
Hope this helps.
Regards,
Bharat
I can point you in the right direction, I hope. You want to learn
basics of Rails first. An excellent starter book would be Patrick
Lenz's Simply Rails 2. After that, I would to a google search on
restful_authentication tutorials. There are a lot of good tutorials
available. Then you would be in a much better position to address the
problem at hand.
You should also keep in mind that most ISPs use dynamically assigned IP
addresses that can change at any time for the same user.
I agree that you must be able to identify the person. Cookies are
insufficient. They can be easily cleared by the user. I use Safari, most
of the time, and I reset it often which quickly and conveniently clears
all cookies.
As another option you could track people by using OpenID if you don't
want to take on the hassles of usernames and passwords. This is what
stackoverflow.com is doing.
I think OpenID a great idea. But, there is a trade-off there. Setting up
an OpenID initially adds even more complication to the end user than a
username and password. The difference is that it's a one-time
complication. The benefit to the end user is that they don't have to
remember 20 passwords for 20 sites. So they will be able to use their
OpenID on many other sites that support it. And for current OpenID users
it involves much less complication. They only need to enter their OpenID
URL and that's it. All you have to do is validate their OpenID.
There's a nice OpenID gem "ruby-openid" that should make implement it
fairly painless.
OK. If you are that far along. Then you may want to create a votes
table something similar to as I show below:
votes:
id - int - created by rails in migrations
question_id, even_id, ... whatever you are trying to track a user vote
on
user_id - foreign key from your users table
voted_on - if you want to explicitly record the time and date
Note that you may or may not want to create voted on explicitly since
if you are using Rails 2.1.0, it will automatically create created_at,
and updated_at giving you the same functionality (more since you have
updated_at field too).
Before saving a user's vote, you want to check in this table (write a
validation function in the controller using before_filter) if the user
has already voted on this question (or event or whatever you are
tracking). If you find an existing record then simply display a flash
message and return false.
I cannot write the code for you, but here is one approach to solving
this problem. Give it a try.