Creating Unique Votes


#1

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.


    #2

    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


    #3

    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


    #4

    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 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


    #5

    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


    #6

    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.


    #7

    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