# Creating Unique Votes

**URL:** <https://www.ruby-forum.com/t/creating-unique-votes/151525>\
**Category:** Rails\
**Created:** [October 22, 2008, 1:34pm UTC](https://www.ruby-forum.com/t/creating-unique-votes/151525 "2008-10-22T13:34:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Leximo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/839c29/32.png) [@Leximo](https://www.ruby-forum.com/u/Leximo)\
**Post date:** [October 22, 2008, 1:34pm UTC](https://www.ruby-forum.com/t/creating-unique-votes/151525/1 "2008-10-22T13:34:44Z")

</div>

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

def create  
@word = Word.find(params[:word\_id])  
@word.votes.create(:user =\> @current\_user)

respond\_to do |format|  
format.html { redirect\_to @word }  
format.js  
end

end

end

# MODEL

class Vote \< ActiveRecord::Base  
belongs\_to :word, :counter\_cache =\> true  
belongs\_to :user  
end

# VIEWS

# Create.js.rs

page.replace\_html ‘vote\_score’, “Score: #{@word.reload.votes.size}”  
page[:vote\_score].visual\_effect :highlight, :duration =\> 2.0  
page[:vote\_score].visual\_effect :pulsate, :duration =\>  
1.5, :collection =\> @word.votes.latest

#Edit.rjs  
page.replace\_html ‘vote\_score’, “Score: #{@word.votes.size}”  
page[:vote\_score].visual\_effect :highlight, :duration =\> 2.0  
page[:vote\_score].visual\_effect :pulsate, :duration =\> 1.5

#Vote.html.erb

- \<%= vote.created\_at.to\_formatted\_s(:short) %\>

I would appreciate some help with figuring this out.

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![Leximo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/839c29/32.png) [@Leximo](https://www.ruby-forum.com/u/Leximo)\
**Post date:** [October 22, 2008, 3:08pm UTC](https://www.ruby-forum.com/t/creating-unique-votes/151525/2 "2008-10-22T15:08:21Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Leximo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/839c29/32.png) [@Leximo](https://www.ruby-forum.com/u/Leximo)\
**Post date:** [October 22, 2008, 3:40pm UTC](https://www.ruby-forum.com/t/creating-unique-votes/151525/3 "2008-10-22T15:40:42Z")

</div>

Could you tell me what code I should write. I’m really new to RoR and  
have no idea how to do that.

On Oct 22, 9:08 am, Bharat R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Leximo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/839c29/32.png) [@Leximo](https://www.ruby-forum.com/u/Leximo)\
**Post date:** [October 22, 2008, 3:59pm UTC](https://www.ruby-forum.com/t/creating-unique-votes/151525/4 "2008-10-22T15:59:28Z")

</div>

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](http://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.

Bharat R. wrote:

> 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

---

<div class="post-metadata">

**Author:** ![Leximo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/839c29/32.png) [@Leximo](https://www.ruby-forum.com/u/Leximo)\
**Post date:** [October 23, 2008, 8:15am UTC](https://www.ruby-forum.com/t/creating-unique-votes/151525/5 "2008-10-23T08:15:30Z")

</div>

Actually I have the Simply Rails 2 book and the Restful\_Authentication  
plugin installed on my app in addition to the open-id.

The problem is adding the unique voting. I’ll take a look at adding an  
extra field.

On Oct 22, 9:59 am, Robert W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Leximo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/839c29/32.png) [@Leximo](https://www.ruby-forum.com/u/Leximo)\
**Post date:** [October 22, 2008, 4:00pm UTC](https://www.ruby-forum.com/t/creating-unique-votes/151525/6 "2008-10-22T16:00:16Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Leximo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/839c29/32.png) [@Leximo](https://www.ruby-forum.com/u/Leximo)\
**Post date:** [October 23, 2008, 2:46pm UTC](https://www.ruby-forum.com/t/creating-unique-votes/151525/7 "2008-10-23T14:46:28Z")

</div>

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.

Bharat
