Here's the situation:
I have a User model, and two modules for authentication: Oauth and Openid. Both of them override ActiveRecord#save
, and have a fair share of implementation logic.
Given that I can tell when the user is trying to login via Oauth vs. Openid, but that both of them have overridden save
, how do "finally" override save
such that I can conditionally call one of the modules' implementations of it?
Here is the base structure of what I'm describing:
module UsesOauth
def self.included(base)
base.class_eval do
def save
puts "Saving with Oauth!"
end
def save_with_oauth
save
end
end
end
end
module UsesOpenid
def self.included(base)
base.class_eval do
def save
puts "Saving with OpenID!"
end
def save_with_openid
save
end
end
end
end
module Sequencer
def save
if using_oauth?
save_with_oauth
elsif using_openid?
save_with_openid
else
super
end
end
end
class User < ActiveRecord::Base
include UsesOauth
include UsesOpenid
include Sequencer
end
I was thinking about using alias_method
like so, but that got too complicated, because I might have 1 or 2 more similar modules. I also tried using those save_with_oauth
methods (shown above), which almost works. The only thing that's missing is that I also need to call ActiveRecord::Base#save
(the super method), so something like this:
def save_with_oauth
# do this and that
super.save
# the rest
end
But I'm not allowed to do that in ruby.
Any ideas for a clever solution to this?
Is that what alias_method_chain
would do? I've avoided that because people seemed to say it was a bad idea.
(Finding things as I go):