TopicLinkClick: convert 'ip' (bigint) -> 'ip_address' (inet)
When accessed over IPv6, the ip address of the user is a 128-bit number, too big for PostgreSQL's bigint data type. Since PostgresSQL has the built-in inet type, which handles both IPv4 and IPv6 addresses, we should use that instead. Where this is done elsewhere in the codebase, the column is called ip_address, so we should follow that convention as well. This migration uses a SQL command to populate the new field from the old one, so as not to rely on the TopicLinkClick model class, which should keep the migration from failing if that class is modified in the future.
This commit is contained in:
parent
c79ab3fc2e
commit
2e478d8537
|
@ -5,10 +5,8 @@ class TopicLinkClick < ActiveRecord::Base
|
|||
belongs_to :topic_link, counter_cache: :clicks
|
||||
belongs_to :user
|
||||
|
||||
has_ip_address :ip
|
||||
|
||||
validates_presence_of :topic_link_id
|
||||
validates_presence_of :ip
|
||||
validates_presence_of :ip_address
|
||||
|
||||
# Create a click from a URL and post_id
|
||||
def self.create_from(args={})
|
||||
|
@ -28,7 +26,7 @@ class TopicLinkClick < ActiveRecord::Base
|
|||
rate_key = "link-clicks:#{link.id}:#{args[:user_id] || args[:ip]}"
|
||||
if $redis.setnx(rate_key, "1")
|
||||
$redis.expire(rate_key, 1.day.to_i)
|
||||
create!(topic_link_id: link.id, user_id: args[:user_id], ip: args[:ip])
|
||||
create!(topic_link_id: link.id, user_id: args[:user_id], ip_address: args[:ip])
|
||||
end
|
||||
|
||||
args[:url]
|
||||
|
@ -43,9 +41,9 @@ end
|
|||
# id :integer not null, primary key
|
||||
# topic_link_id :integer not null
|
||||
# user_id :integer
|
||||
# ip :integer not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# ip_address :string not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
require 'ipaddr'
|
||||
|
||||
class ChangeIpToInetInTopicLinkClicks < ActiveRecord::Migration
|
||||
def up
|
||||
add_column :topic_link_clicks, :ip_address, :inet
|
||||
|
||||
execute "UPDATE topic_link_clicks SET ip_address = inet(
|
||||
(ip >> 24 & 255) || '.' ||
|
||||
(ip >> 16 & 255) || '.' ||
|
||||
(ip >> 8 & 255) || '.' ||
|
||||
(ip >> 0 & 255)
|
||||
);"
|
||||
|
||||
change_column :topic_link_clicks, :ip_address, :inet, { :null => false }
|
||||
remove_column :topic_link_clicks, :ip
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
|
@ -26,7 +26,7 @@ describe TopicLinkClick do
|
|||
|
||||
context 'create' do
|
||||
before do
|
||||
TopicLinkClick.create(topic_link: @topic_link, ip: '192.168.1.1')
|
||||
TopicLinkClick.create(topic_link: @topic_link, ip_address: '192.168.1.1')
|
||||
end
|
||||
|
||||
it 'creates the forum topic link click' do
|
||||
|
@ -39,7 +39,7 @@ describe TopicLinkClick do
|
|||
end
|
||||
|
||||
it 'serializes and deserializes the IP' do
|
||||
TopicLinkClick.first.ip.to_s.should == '192.168.1.1'
|
||||
TopicLinkClick.first.ip_address.to_s.should == '192.168.1.1'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -236,7 +236,7 @@ describe TopicLink do
|
|||
it 'has the correct results' do
|
||||
TopicLink.extract_from(post)
|
||||
topic_link = post.topic.topic_links.first
|
||||
TopicLinkClick.create(topic_link: topic_link, ip: '192.168.1.1')
|
||||
TopicLinkClick.create(topic_link: topic_link, ip_address: '192.168.1.1')
|
||||
|
||||
counts_for[post.id].should be_present
|
||||
counts_for[post.id].find {|l| l[:url] == 'http://google.com'}[:clicks].should == 0
|
||||
|
|
Loading…
Reference in New Issue