Model.find_by_attribute only called the first time

View: New views
8 Messages — Rating Filter:   Alert me  

Model.find_by_attribute only called the first time

by Hiro Protagonist-6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


# This is a sanitized example of what I am doing at work and was
perplexed

def Person.find_by_name(*params)
    puts "hello world!"
    params.first.chop! if params.first.last == "."
    super
end

# It strips the trailing . and puts hello world!
>> Person.find_by_name("Chris.")
"hello world!"
=> #<Person id: 1, :name: "Chris">

# I hit up arrow and enter

=> nil

# Why is the method not actually being called the second time?
# I can handle never working and always working, but always working
once I can't handle.

Thanks,
Chris Lundquist

--~--~---------~--~----~------------~-------~--~----~
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 rubyonrails-core@...
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Model.find_by_attribute only called the first time

by Ryan Bigg-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

May I suggest aliasing the method instead of trying to call super?

alias_method :old_find_by_name, :find_by_name

def Person.find_by_name(*params)
  params.first.chop! if params.first.last == "."
  old_find_by_name(params)
end


2009/11/10 Hiro Protagonist <rampantdurandal@...>

# This is a sanitized example of what I am doing at work and was
perplexed

def Person.find_by_name(*params)
   puts "hello world!"
   params.first.chop! if params.first.last == "."
   super
end

# It strips the trailing . and puts hello world!
>> Person.find_by_name("Chris.")
"hello world!"
=> #<Person id: 1, :name: "Chris">

# I hit up arrow and enter

=> nil

# Why is the method not actually being called the second time?
# I can handle never working and always working, but always working
once I can't handle.

Thanks,
Chris Lundquist





--
Ryan Bigg

--~--~---------~--~----~------------~-------~--~----~
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 rubyonrails-core@...
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Model.find_by_attribute only called the first time

by Michael Koziarski :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> May I suggest aliasing the method instead of trying to call super?
> alias_method :old_find_by_name, :find_by_name
> def Person.find_by_name(*params)
>   params.first.chop! if params.first.last == "."
>   old_find_by_name(params)
> end

super won't work here because the method isn't defined on a parent of
Person, it's defined on person itself.  So what's happening is that
the call to method missing is generating a *new* implementation of
find_by_name which simply does the find, without your changes.

We could fix this for rails 3.0 by moving those generated methods from
Person to a module included in person, but for 2.3 you'll have to do
as Ryan suggests and use aliasing, or just call
all(:conditions=>{:first_name=>params.first}) instead of super.

--
Cheers

Koz

--~--~---------~--~----~------------~-------~--~----~
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 rubyonrails-core@...
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Model.find_by_attribute only called the first time

by Hiro Protagonist-6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Koz and Ryan,

Now that you point it out, I see how #method_missing calls find, then
find thinks I'm retarded and over writes my method by doing a class
eval. Thus removing my original code.

Am I figuring that right?

I've always had trouble generating aliases to singleton methods.

I seem to recall the following syntax doesn't work
alias self.old_name self.new_name

but I might be confusing trying

alias old_name self.new_name

Thank you for your insights,
Chris Lundquist



On Nov 9, 2:37 pm, Michael Koziarski <mich...@...> wrote:

> > May I suggest aliasing the method instead of trying to call super?
> > alias_method :old_find_by_name, :find_by_name
> > def Person.find_by_name(*params)
> >   params.first.chop! if params.first.last == "."
> >   old_find_by_name(params)
> > end
>
> super won't work here because the method isn't defined on a parent of
> Person, it's defined on person itself.  So what's happening is that
> the call to method missing is generating a *new* implementation of
> find_by_name which simply does the find, without your changes.
>
> We could fix this for rails 3.0 by moving those generated methods from
> Person to a module included in person, but for 2.3 you'll have to do
> as Ryan suggests and use aliasing, or just call
> all(:conditions=>{:first_name=>params.first}) instead of super.
>
> --
> Cheers
>
> Koz
--~--~---------~--~----~------------~-------~--~----~
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 rubyonrails-core@...
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Model.find_by_attribute only called the first time

by Ryan Bigg-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I've just realised that because this is a dynamic finder the "power" of method_missing is what's going to stop you from being able to alias this method. This method appears to not be defined until method_missing catches it and defines it then. I've tried also calling the method before aliasing it (thereby defining it) but without much luck:

user.rb:

find_by_name(nil)
  
  class_eval do 
    alias_method :old_find_by_name, :find_by_name
  end

NameError: undefined method `find_by_name' for class `User'

I'm really interested in how this would be done now.

2009/11/10 Hiro Protagonist <rampantdurandal@...>

Koz and Ryan,

Now that you point it out, I see how #method_missing calls find, then
find thinks I'm retarded and over writes my method by doing a class
eval. Thus removing my original code.

Am I figuring that right?

I've always had trouble generating aliases to singleton methods.

I seem to recall the following syntax doesn't work
alias self.old_name self.new_name

but I might be confusing trying

alias old_name self.new_name

Thank you for your insights,
Chris Lundquist



On Nov 9, 2:37 pm, Michael Koziarski <mich...@...> wrote:
> > May I suggest aliasing the method instead of trying to call super?
> > alias_method :old_find_by_name, :find_by_name
> > def Person.find_by_name(*params)
> >   params.first.chop! if params.first.last == "."
> >   old_find_by_name(params)
> > end
>
> super won't work here because the method isn't defined on a parent of
> Person, it's defined on person itself.  So what's happening is that
> the call to method missing is generating a *new* implementation of
> find_by_name which simply does the find, without your changes.
>
> We could fix this for rails 3.0 by moving those generated methods from
> Person to a module included in person, but for 2.3 you'll have to do
> as Ryan suggests and use aliasing, or just call
> all(:conditions=>{:first_name=>params.first}) instead of super.
>
> --
> Cheers
>
> Koz




--
Ryan Bigg

--~--~---------~--~----~------------~-------~--~----~
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 rubyonrails-core@...
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Model.find_by_attribute only called the first time

by Hiro Protagonist-6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


I just wanted a :before_find hook, saw the mail history from here
during 2006 and they said do

 def find
# Before Find.
super
# After Find
end

But now we know how that turns out.

Ultimately it isn't important to my app, but it would be nice when me
or users forget trailing .s

Thanks,
Chris Lundquist


On Nov 9, 3:23 pm, Ryan Bigg <radarliste...@...> wrote:

> I've just realised that because this is a dynamic finder the "power" of
> method_missing is what's going to stop you from being able to alias this
> method. This method appears to not be defined until method_missing catches
> it and defines it then. I've tried also calling the method before aliasing
> it (thereby defining it) but without much luck:
>
> user.rb:
>
> find_by_name(nil)
>
>   class_eval do
>     alias_method :old_find_by_name, :find_by_name
>   end
>
> NameError: undefined method `find_by_name' for class `User'
>
> I'm really interested in how this would be done now.
>
> 2009/11/10 Hiro Protagonist <rampantduran...@...>
>
>
>
>
>
>
>
> > Koz and Ryan,
>
> > Now that you point it out, I see how #method_missing calls find, then
> > find thinks I'm retarded and over writes my method by doing a class
> > eval. Thus removing my original code.
>
> > Am I figuring that right?
>
> > I've always had trouble generating aliases to singleton methods.
>
> > I seem to recall the following syntax doesn't work
> > alias self.old_name self.new_name
>
> > but I might be confusing trying
>
> > alias old_name self.new_name
>
> > Thank you for your insights,
> > Chris Lundquist
>
> > On Nov 9, 2:37 pm, Michael Koziarski <mich...@...> wrote:
> > > > May I suggest aliasing the method instead of trying to call super?
> > > > alias_method :old_find_by_name, :find_by_name
> > > > def Person.find_by_name(*params)
> > > >   params.first.chop! if params.first.last == "."
> > > >   old_find_by_name(params)
> > > > end
>
> > > super won't work here because the method isn't defined on a parent of
> > > Person, it's defined on person itself.  So what's happening is that
> > > the call to method missing is generating a *new* implementation of
> > > find_by_name which simply does the find, without your changes.
>
> > > We could fix this for rails 3.0 by moving those generated methods from
> > > Person to a module included in person, but for 2.3 you'll have to do
> > > as Ryan suggests and use aliasing, or just call
> > > all(:conditions=>{:first_name=>params.first}) instead of super.
>
> > > --
> > > Cheers
>
> > > Koz
>
> --
> Ryan Bigg
--~--~---------~--~----~------------~-------~--~----~
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 rubyonrails-core@...
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Model.find_by_attribute only called the first time

by Matt Jones :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Nov 9, 2009, at 7:06 PM, Hiro Protagonist wrote:

>
> I just wanted a :before_find hook, saw the mail history from here
> during 2006 and they said do
>
> def find
> # Before Find.
> super
> # After Find
> end
>
> But now we know how that turns out.
>
> Ultimately it isn't important to my app, but it would be nice when me
> or users forget trailing .s
>

You might also want to think about doing this in a before_filter;  
cleaning trailing spaces off of request parameters feels pretty  
controller-y to me.

--Matt Jones


--~--~---------~--~----~------------~-------~--~----~
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 rubyonrails-core@...
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---


Re: Model.find_by_attribute only called the first time

by Hiro Protagonist-6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


I'm working with BIND files and DNS. Sometimes the method isn't called
from a controller. Sometimes it will be called from a cron tab and
script/runner

On Nov 9, 4:30 pm, Matt Jones <al2o...@...> wrote:

> On Nov 9, 2009, at 7:06 PM, Hiro Protagonist wrote:
>
>
>
> > I just wanted a :before_find hook, saw the mail history from here
> > during 2006 and they said do
>
> > def find
> > # Before Find.
> > super
> > # After Find
> > end
>
> > But now we know how that turns out.
>
> > Ultimately it isn't important to my app, but it would be nice when me
> > or users forget trailing .s
>
> You might also want to think about doing this in a before_filter;  
> cleaning trailing spaces off of request parameters feels pretty  
> controller-y to me.
>
> --Matt Jones
--~--~---------~--~----~------------~-------~--~----~
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 rubyonrails-core@...
To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---