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