Last active
April 4, 2020 04:56
-
-
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…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This was super helpful, thanks man!