On 16 Jan 2008, at 15:37, Jan De Poorter wrote:
> > Hi, > > When you call a dynamic finder action (in your case find_by_ip), the > ruby method_missing function is called. This magic functions takes the > function you requested and creates it, which causes your function to > be overwritten in favor of the created function. When you reload!, > your model gets loaded again, and the created function is overwritten > again. This isn't to be expected ofcourse. I reached that conclusion over on rails-talk, but I'm not entirely sure what do about it check whether the method that's about to be created exists and if so use a different (but predictable) name so that in your own find_by_x function you can call the 'normal' find_by_x Fred > > > Could you file a bug about this on http://dev.rubyonrails.com ? > > Regards, > DefV > > On 16 Jan 2008, at 16:26, Carr0t wrote: > >> >> As suggested in my thread in Ruby On Rails: Talk (http:// >> groups.google.com/group/rubyonrails-talk/browse_thread/thread/ >> 66ae64e6581a3896) i'm posting an issue i'm having with Rails 2.0 and >> overloading find_by methods here. Hoepfully someone can either >> suggest >> what I am doing wrong and should be doing instead to get this >> working, >> or tell me where to submit a bug report so this can get fixed if it >> is >> not desired behaviour: >> >> This came up when I migrated from rails 1.2.3 to 2.0.2. Previously, >> my >> code was working fine. I am using >> a mysql backend database, in which I am storing IPv4 addresses as 32 >> bit unsigned integers. Of course, I don't want my users to have to >> enter the IP they are searching for in this fashion, nor do I want to >> have to make the conversion myself every time I call the find_by_ip >> function or find_or_create_by_ip function for the model, so I have >> overloaded those two functions. find_by_ip now reads as follows: >> >> def self.find_by_ip(ip) >> super(NetAddr::CIDR.create(ip).to_i) >> end >> >> This works, the first time Ip.find_by_ip(address) is called (this >> test >> done in script/console): >> >>>> ip = Ip.find_by_ip("10.21.1.8") >> => #<Ip id: 13, ip: 169148680> >> >> However any subsequent calls to find_by_ip just return nil, even for >> the same IP address, until the environment is reloaded: >> >>>> reload! >> Reloading... >> => true >>>> ip = Ip.find_by_ip("10.21.1.8") >> => #<Ip id: 13, ip: 169148680> >>>> ip = Ip.find_by_ip("10.21.1.8") >> => nil >> >> If I add some puts statements in my overloaded find_by_ip, they never >> get printed out after the first call to it has been done. Equally, if >> I call find_by_ip with a 32 bit int form of an IPv4 address it works >> reliably: >> >> def self.find_by_ip(ip) >> puts "Testing\n" >> super(NetAddr::CIDR.create(ip).to_i) >> end >> >> ?> reload! >> Reloading... >> => true >>>> ip = Ip.find_by_ip("10.21.1.8") >> Testing >> => #<Ip id: 13, ip: 169148680> >>>> ip = Ip.find_by_ip("10.21.1.8") >> => nil >>>> ip = Ip.find_by_ip(169148680) >> => #<Ip id: 13, ip: 169148680> >> >> It is as if, after the first call to my overloaded find_by_ip, rails >> decides to ignore my overloaded function and go straight to the base >> functionality it has for creating find_by functions. The suggestion >> was that, in Rails 2.0, instead of calling the method_missing >> function >> every time I call super() from within a find_by_function (as there is >> no specific find_by function of that name in ActiveRecord::Base), it >> instead creates the find_by_ip function, which overwrites my one, and >> subsequent calls hit that and thus don't get the IP address converted >> to an int, and thus don't find any matching record in the database. I >> am assuming this change was made for speed, as as long as you are not >> overloading a find_by function it will be faster if the function is >> pre-generated instead of having to be created every time it is >> called, >> but what can I do to fix this? Is the best fix to call my 'overload' >> function get_by_ip (or similar), so that the created find_by_ip >> function doesn't have a namespace conflict, and then call >> self.find_by_ip from within that once I have got my IP in numerical >> format? This does work, but does mean that my code is sometimes using >> find_by and sometimes using get_by (or whatever), which makes it >> harder for anyone following to debug as it is not consistent. >> >> Thanks >> >> Dan Meyers >> Network Support, Lancaster University >>> > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
