Forum: Ruby on Rails Creating Unique Votes

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ca4d31b9ef15829f4ce3e75e3ca1042d?d=identicon&s=25 Leximo (Guest)
on 2008-10-22 13:34
(Received via mailing list)
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
<li><%= vote.created_at.to_formatted_s(:short) %></li>

I would appreciate some help with figuring this out.

Thanks in advance.
D3fc5887a2f39f2e0c8989d39ce5e6f9?d=identicon&s=25 Bharat Ruparel (bruparel)
on 2008-10-22 15:08
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
Ca4d31b9ef15829f4ce3e75e3ca1042d?d=identicon&s=25 Leximo (Guest)
on 2008-10-22 15:40
(Received via mailing list)
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 Ruparel <rails-mailing-l...@andreas-s.net>
280b78a61a968391b7e07e912be102a8?d=identicon&s=25 Robert Walker (robert4723)
on 2008-10-22 15:59
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.

Bharat Ruparel 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
D3fc5887a2f39f2e0c8989d39ce5e6f9?d=identicon&s=25 Bharat Ruparel (bruparel)
on 2008-10-22 16:00
(Received via mailing list)
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.
Ca4d31b9ef15829f4ce3e75e3ca1042d?d=identicon&s=25 Leximo (Guest)
on 2008-10-23 08:15
(Received via mailing list)
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 Walker <rails-mailing-l...@andreas-s.net>
D3fc5887a2f39f2e0c8989d39ce5e6f9?d=identicon&s=25 Bharat Ruparel (bruparel)
on 2008-10-23 14:46
(Received via mailing list)
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
This topic is locked and can not be replied to.