I have a Ruby on Rails 3.2 application where users are able to upload videos directly to youtube with the Youtube_it Rails gem. After the video is uploaded, the people are able to vote on the videos. I have it setup now where anyone can vote on the videos and they don't have to register(using devise) to vote on the videos.
I would like to limit the votes to 1 vote per day per IP address. If a person has voted from an IP address, they should not be able to vote again for 24 hours.
I'm new to rails and I can't seem to figure out how to implement this. I think I would have to create a model to store the users IP address in it with request.remote_ip. How would I limit their voting to once per day?
My 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
My videos show view
<%= 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 %>
Videos controller
def vote_up
@video = Video.find(params[:id])
@video.update_attribute(:votes_up, (@video.votes_up.to_i + 1))
redirect_to @video
end
# 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