On Tue, Apr 26, 2011 at 4:44 PM, ivanpoval <[email protected]> wrote:
> Hi, here is the example of the wrong usage of the `super` keyword
> trying to override the attribute method.
>
> class User < ActiveRecord::Base
>  def name
>    super.to_s.capitalize
>  end
> end
>
> The result of this code looks 'pseudo'-correct and some people assume
> it's fine to use that like if it were self[:name].to_s.capitalize
> If we take a look at the code below - the results are different:
>
> class User < ActiveRecord::Base
>  def name
>    'hi ' + super.to_s.capitalize
>  end
> end
>
> u = User.first
> p u.name # => 'hi Hi bob'
> p u.name # => 'hi Bob'
> p u.name # => 'hi Bob'
>
> My question is why the first call to u.name produces that result.
> I'm looking at
> if self.class.generated_methods.include?(method_name)
>  return self.send(method_id, *args, &block)
> end
>
> in
> module ActiveRecord
>  module AttributeMethods
>    def method_missing
>
> but need some help to figure the things out.
> Simply want to know what is actually happening...

The first time you call name, your super call actually calls
method_missing, since the name method doesn't exist higher in the
method chain.  method_missing doesn't think the attribute methods have
been defined yet, so it calls a method to define them in an anonymous
module included in the class, then calls the method again.  Basically,
the first time you call it:

User#name -> ActiveRecord::AttributeMethods#method_missing ->
User#name -> generated_methods_module#name

Future calls don't hit method_missing because
generated_methods_module#name already exists:

User#name -> generated_methods_module#name

Your example works fine in Sequel, BTW, because Sequel sets up the
attribute methods in an anonymous module included in the class at
class definition time, instead of when the attribute method is first
called.  I wouldn't be surprised if the ActiveRecord way of defining
attribute methods is subject to a race condition in threaded code, in
addition to the problem you are experiencing.

Jeremy

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