Hi all, I am trying store IP addresses in a database. In my old PHP days when I wrote the SQL i used the INET_ATON and INET_NTOA functions in MySQL to to the conversions of the address when I inserted or pulled the rows from the database. I would like to do something similar with my ActiveRecord model in Rails as storing the IP as an integer is much more efficient than in its dot format. My question is how do I do it? Is there a way for me to setup my model so that whenever it saves it converts the stored IP and when it finds a record it automatically converts it back to the dot format? Is there a way I can use the MySQL functions? Or could I just always keep it in the integer state, but have accessors in the class convert it when I access it? Thanks Peer -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Fri, 2007-06-01 at 22:47 +0200, Peer Allan wrote:> My question is how do I do it? Is there a way for me to setup my model > so that whenever it saves it converts the stored IP and when it finds a > record it automatically converts it back to the dot format? Is there a > way I can use the MySQL functions? Or could I just always keep it in > the integer state, but have accessors in the class convert it when I > access it? >Yow, no. Wait, yes. You could use a activerecord callback for before_save to change the IP before writing to the database: http://railsmanual.com/module/ActiveRecord::Callbacks but there is no callback for retrieval. Ahha, but we can just overwrite the method in the model: def ip self.ip.gsub /2/, ''3'' end Would replace 2s with 3s. But really, why not just store it as a string? Why do you want to store it as a number? It isn''t a number, it''s an IP. Good luck! -- Matthew Beale :: 607 227 0871 Resume & Portfolio @ http://madhatted.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Matthew, Here are some of the reasons why I want to store the IP a a number: http://arjen-lentz.livejournal.com/44290.html http://forums.mysql.com/read.php?21,49094,49094#msg-49094 The table that I will be using will be getting large (a similar system we have right now is growing at about 1 million records a month) and using 4 bytes instead of 15 will really add up over time. (Yes, I know how cheap storage is nowadays, but I would like to avoid the adventure of a full drives as long as possible, been there done that!) I was looking to see if there was a way if I could mimic the "serialize" functionality, but I''m afraid I am going to have to study ActiveRecord a lot more first. Peer Matthew Beale wrote:> On Fri, 2007-06-01 at 22:47 +0200, Peer Allan wrote: >> My question is how do I do it? Is there a way for me to setup my model >> so that whenever it saves it converts the stored IP and when it finds a >> record it automatically converts it back to the dot format? Is there a >> way I can use the MySQL functions? Or could I just always keep it in >> the integer state, but have accessors in the class convert it when I >> access it? >> > > Yow, no. Wait, yes. You could use a activerecord callback for > before_save to change the IP before writing to the database: > > http://railsmanual.com/module/ActiveRecord::Callbacks > > but there is no callback for retrieval. Ahha, but we can just overwrite > the method in the model: > > def ip > self.ip.gsub /2/, ''3'' > end > > Would replace 2s with 3s. > > But really, why not just store it as a string? Why do you want to store > it as a number? It isn''t a number, it''s an IP. > > Good luck! > > -- > Matthew Beale :: 607 227 0871 > Resume & Portfolio @ http://madhatted.com-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
require ''ipaddr'' # INET_ATON IPAddr.new("192.168.0.10").to_i # => 3232235530 # INET_NTOA IPAddr.new(3232235530, Socket::AF_INET).to_s # => "192.168.0.10" HTH - H On 6/2/07, Peer Allan <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > Hi Matthew, > > Here are some of the reasons why I want to store the IP a a number: > > http://arjen-lentz.livejournal.com/44290.html > http://forums.mysql.com/read.php?21,49094,49094#msg-49094 > > The table that I will be using will be getting large (a similar system > we have right now is growing at about 1 million records a month) and > using 4 bytes instead of 15 will really add up over time. (Yes, I know > how cheap storage is nowadays, but I would like to avoid the adventure > of a full drives as long as possible, been there done that!) > > I was looking to see if there was a way if I could mimic the "serialize" > functionality, but I''m afraid I am going to have to study ActiveRecord a > lot more first. > > Peer > > Matthew Beale wrote: > > On Fri, 2007-06-01 at 22:47 +0200, Peer Allan wrote: > >> My question is how do I do it? Is there a way for me to setup my model > >> so that whenever it saves it converts the stored IP and when it finds a > >> record it automatically converts it back to the dot format? Is there a > >> way I can use the MySQL functions? Or could I just always keep it in > >> the integer state, but have accessors in the class convert it when I > >> access it? > >> > > > > Yow, no. Wait, yes. You could use a activerecord callback for > > before_save to change the IP before writing to the database: > > > > http://railsmanual.com/module/ActiveRecord::Callbacks > > > > but there is no callback for retrieval. Ahha, but we can just overwrite > > the method in the model: > > > > def ip > > self.ip.gsub /2/, ''3'' > > end > > > > Would replace 2s with 3s. > > > > But really, why not just store it as a string? Why do you want to store > > it as a number? It isn''t a number, it''s an IP. > > > > Good luck! > > > > -- > > Matthew Beale :: 607 227 0871 > > Resume & Portfolio @ http://madhatted.com > > > -- > Posted via http://www.ruby-forum.com/. > > > >-- Husein Choroomi Yucca Intelligence Development http://www.YuccaHQ.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Peer, You can store the IP as an integer in the database and convert to and from a string using Ruby. Check out this class: http://ruby-doc.org/stdlib/libdoc/ipaddr/rdoc/classes/IPAddr.html This seems to work: class Address < ActiveRecord::Base require ''IPAddr'' def self.find_by_ip(value) find :first, :conditions => {:ip => IPAddr.new(value).to_i} end # Convert from integer - IPAddr doesn''t seem to have this method def ip [read_attribute(:ip)].pack("N").unpack("C*").join "." end def ip=(value) write_attribute(:ip, IPAddr.new(value).to_i) end end Hope this helps. -=nathan --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks Husein, I think I will combining all the suggestions I have received on this thread so that I end up with something like this: class Address < ActiveRecord::Base require ''IPAddr'' before_save :convert_ip def self.find_by_ip(value) find :first, :conditions => {:ip => IPAddr.new(value).to_i} end def ip convert_ip IPAddr.new(read_attribute(:ip), Socket::AF_INET).to_s end def ip=(value) write_attribute(:ip, IPAddr.new(value).to_i) end def convert_ip if read_attribute(:ip) =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/ write_attribute(:ip, IPAddr.new(read_attribute(:ip)).to_i) end end end I just whipped this up so I obviously have not tested it in any way. Peer Husein Choroomi wrote:> require ''ipaddr'' > > # INET_ATON > IPAddr.new("192.168.0.10").to_i # => 3232235530 > > # INET_NTOA > IPAddr.new(3232235530, Socket::AF_INET).to_s # => "192.168.0.10" > > HTH > - H > > On 6/2/07, Peer Allan <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote: >> using 4 bytes instead of 15 will really add up over time. (Yes, I know >> > On Fri, 2007-06-01 at 22:47 +0200, Peer Allan wrote: >> > >> > >> -- >> Posted via http://www.ruby-forum.com/. >> >> > >> > > > -- > Husein Choroomi > Yucca Intelligence Development > http://www.YuccaHQ.com-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---