开发者

Limit voting using cookies

开发者 https://www.devze.com 2023-04-12 00:47 出处:网络
I would like for visitors to only be able to vote on each link once. I understand that if they clear their cookies, they\'ll be able to vote again. How would I implement this feature in rails? I\'ve a

I would like for visitors to only be able to vote on each link once. I understand that if they clear their cookies, they'll be able to vote again. How would I implement this feature in rails? I've attached my files below. T开发者_C百科hanks

Controller https://gist.github.com/1274274

View https://gist.github.com/1274275


I wouldn't store this in cookies or even session. You should track these in votes table which contains the user_id and a link_id.

Every time a user votes, check for a record in this table and if one exists then throw an error. If one doesn't exist then insert a record into this table and increment the votes count on the links table, perhaps using a counter cache.


I would not recommend doing it that way but if you insist I would say you should create a hash with the ids of the link as keys and their values set to true or false according to the type of vote.

I would change your controller like this:

def up
    @link = Link.find(params[:id])

    session[:voting] ||= {}

    unless session[:voting][@link.id]
        if session[:voting][@link.id].nil?
            points = 1
        else
            points = 2

        @link.update_attribute :points, @link.points + points

        session[:voting][@link.id] = true
    end

    redirect_to :action => :index 
end

def down 
    @link = Link.find(params[:id])

    session[:voting] ||= {}

    unless session[:voting][@link.id] == false
        if session[:voting][@link.id]
            points = 2
        else
            points = 1

        @link.update_attribute :points, @link.points - points

        session[:voting][@link.id] = false
    end

    redirect_to :action => :index 
end

This logic should belong to the model but we shouldn't access the session variable inside the model. You can refactor this code inside the model and just pass the session to it from the controller. It would be something like this:

def vote type, session
    return if session[:voting][id] == type

    added_points = session[:voting][id].nil? ? 1 : 2

    update_attribute :points, points + (type ? added_points: -added_points)

    session[:voting][id] = type
end

Find more about sessions here: http://guides.rubyonrails.org/action_controller_overview.html#session

Hope that works.

0

精彩评论

暂无评论...
验证码 换一张
取 消