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
-~----------~----~----~----~------~----~------~--~---

Reply via email to