Skip to content

Instantly share code, notes, and snippets.

@dsggregory
Last active April 4, 2020 04:56
Show Gist options
  • Save dsggregory/6336097 to your computer and use it in GitHub Desktop.
Save dsggregory/6336097 to your computer and use it in GitHub Desktop.
Store an IPv4 or IPv6 network number address in a varbinary(16) column using rails ActiveRecord. This is a decent example of using code to perform the v4/v6 conversion instead of the database. VARBINARY(16) allows one to store the numeric value of an IP address so that you can perform range queries and manage a consistent form with respect to al…
require 'ipaddr'
class Ip < ActiveRecord::Base
attr_accessible :ip, :addr, :other_columns
# The 'addr' accessor is what you use to properly set/get the 'ip' column.
# This sets an instance variable to store the IPAddr class representing the
# ip column in either IPv4 or IPv6.
attr_accessor :addr
validates_presence_of :addr, :message => "Invalid or empty IP Address"
after_find :init_addr
# Store the string rep of a v4/6 address into the ip column
def addr=(str)
begin
@addr = IPAddr.new(str)
rescue => e
errors.add(:addr, e.to_s)
end
# Set ip to a string of bytes in network-order so that ActiveRecord will
# properly cast the data on insert into the varbinary.
self.ip = @addr.hton if([email protected]?)
end
# Returns the canonical string form of the ip address
def addr
@addr.to_s
end
# Returns the IPAddr class
def ipaddr
@addr
end
# Return true if the current record (ip) is an IPv6 address
def is_ipv6?
if (!self.ip.nil?)
@addr.ipv6?
else
false
end
end
private
# After reading a record, set @addr to the IPAddr of the ip column.
def init_addr
# From the DB, ip is a string of bytes in network-order.
@addr = IPAddr.new_ntoh(ip)
end
end
@mecampbellsoup
Copy link

This was super helpful, thanks man!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment