2014-05-20 71 views
1

我有一个Ruby on Rails 3.2应用程序,用户可以通过Youtube_it Rails gem将视频直接上传到youtube。视频上传后,人们可以对视频进行投票。现在我已经设置了任何人都可以对视频进行投票,并且他们不必注册(使用设计)对视频进行投票。Rails按IP地址每次限制每天投票1次

我想限制每个IP地址每天投票1票。如果一个人从IP地址投票,他们不应该能够24小时投票。

我是新来的铁轨,我似乎无法弄清楚如何实现这一点。我想我必须创建一个模型来存储用request.remote_ip中的用户IP地址。我如何将他们的投票限制为每天一次?

我的routes.rb

resources :videos do 
collection do 
    put '/vote_up/:id' => "videos#vote_up", :as => :vote_up 
end 
new do 
    post :upload 
    get :save_video 
end 
end 

我的视频显示视图

<%= link_to vote_up_videos_url(@video.id), class: "btn btn-main", :method => :put do %> 
    <i class="fa fa-thumbs-up"></i> Upvote this video 
<% end %> 

视频控制器

def vote_up 
@video = Video.find(params[:id]) 
@video.update_attribute(:votes_up, (@video.votes_up.to_i + 1)) 
redirect_to @video 
end 
+0

你会怎么做,如果有一个以上的用户在IP地址?也许有两个人在一个地址,或者使用运营商级NAT的运营商可能会有数千个用户使用一个IP地址。 –

+0

用户是不是应该能够在同一个视频或任何视频上再次投票?只能注册用户投票吗? – spickermann

+0

你不想这样做。您无法控制并且无法知道请求IP地址来自哪里。由于缺乏IPv4地址,ISP越来越多地被迫实施NAT,这意味着您看到的一个IP地址可以轻松映射到数百个个人。组织(图书馆,wifi点,大学)和小区连接也是如此。 –

回答

1
# in controller 
def vote_up 
video = Video.find(params[:id]) 
video.vote!(request.ip) 

redirect_to video 
end 

# in video model 
def vote!(ip) 
    unless Vote.recent.exists?(:ip => ip, :video_id => id) 
    increment!(:votes_up) 
    Vote.create(:ip => ip, :video_id => id) 
    end 
end 

# in vote model 
class Vote < ActiveRecord::Base 
    scope :recent, -> { where("created_at > ?", 24.hours.ago) } 
end 

# migration 
class CreateVotes < ActiveRecord::Migration 
    def change 
    create_table :votes do |t| 
     t.integer :video_id 
     t.string :ip 
    end 
    add_index :votes, :video_id, :ip 
    end 
end 
+0

这适用于我所需要的。对此,我真的非常感激。 – stiweb2003