A question on a couple things relating to extending a class and the use
of
super.
In my main application I have the following class which extends an
engine
class:
class User < ActiveRecord::Base
def self.find_for_database_authentication(login_value,
omniauth_provider=nil, omniauth_uid=nil)
super if login_value
where(‘omniauth_provider=? AND omniauth_uid=?’, omniauth_provider,
omniauth_uid)
end
end
And the engine has this class:
class User < ActiveRecord::Base
def self.find_for_database_authentication(login_value)
where([“username = :value OR email = :value”, { :value =>
login_value
}]).first
end
end
When I run a spec to try out the method, I get this error:
Failure/Error:
User.find_for_database_authentication(@user.username).class == User
NoMethodError:
super: no superclass method `find_for_database_authentication’
for
#Class:0x1057bbfa0
I do understand why – my application class is not a subclass of the
engine
class, I am just extending the class. This leaves me with the question
if
there is a way to have access to the original method (like using super
in a
subclass situation) so I would not have to duplicate that code (I would
have
subclassed my class to the engine class but is a bit nasty as they share
the
same name, and that is structurally how the app is loaded)?
Also, I am confused also as to why I see in places that to extend a
class
they use “MyClass.class_eval do …” whereas it seems that if I just
do
what I have above, I get the same ability. Am I missing something?
On Wed, May 11, 2011 at 12:52 PM, Frederick C. < [email protected]> wrote:
You are reopening the class (ie adding/changing methods in User), not
subclassing it, so super is looking for methods in activerecord::base.
Did you want to subclass User instead?
I tried but the thing is that the way the engine loads, the engine class
and
my class have the same name and reside in the local app. I guess I could
give my class a different name to subclass it if I dont want to dup the
code. Was just wondering if there was some other way but logically does
not
seem that there is.
You another way is to use alias_method_chain - you’d do something like
class Foo
class << self
def something_with_foo
end
alias_method_chain :something, :foo
end
end
end
What this does is rename the existing something method to
something_without_foo and renames your something_with_foo method to
something. Instead of calling super you call something_without_foo to
call the old something_method
On Wed, May 11, 2011 at 3:29 PM, Frederick C. < [email protected]> wrote:
super.
I tried but the thing is that the way the engine loads, the engine class
class Foo
What this does is rename the existing something method to
something_without_foo and renames your something_with_foo method to
something. Instead of calling super you call something_without_foo to
call the old something_method
Oh, that is interesting. I guess which would have be used carefully or
could
get confusing. This will be fun to play with. Thanks!
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.