I'm building a rails engine that uses the "acts as" format to establish relationships with the parent application's User model.
module Cornerstone
module ActsAsCornerstoneUser
extend ActiveSupport::Concern
module ClassMethods
def acts_as_cornerstone_user(options = {})
#= Associations
has_many :cornerstone_discussions
#= Options
Cornerstone::Config.auth_with << options[:auth_with] if options[:auth_with]
Cornersto开发者_开发问答ne::Config.auth_with.flatten!
end
end
module InstanceMethods
end
end
ActiveRecord::Base.send :include, ActsAsCornerstoneUser
end
I would like for a developer to be able to specify a helper method name using the :auth_with
option. The idea is that the developer will specify a helper method in the parent application that will return the signed in user for that session.
My question is once the developer has specified the auth_with
option, how can I call that parent application's method??
Is there a better approach to obtaining the parent application's signed in user? I'd like it to be as flexible as possible such that it is not dependent on simply calling current_user
.
Something like this should work, as long as you have only one cornerstone user defined in your application :
module Cornerstone
module ActsAsCornerstoneUser
extend ActiveSupport::Concern
module ClassMethods
def acts_as_cornerstone_user(options = {})
#= Associations
has_many :cornerstone_discussions
#= Options
Cornerstone::Config.auth_with = options[:auth_with] if options[:auth_with]
end
end
module InstanceMethods
end
def self.included(base)
base.extend(ClassMethods)
base.include(InstanceMethods)
end
end
ActiveRecord::Base.send :include, ActsAsCornerstoneUser
end
Then define a helper in your gem (ie. in app/helpers/cornerstone_helper.rb
) :
module Cornerstone
module CornerStoneHelper
def current_cornerstone_user
Config.auth_with.call(controller)
end
end
end
The acts_as_cornerstone
method is the used like this :
class MyUser < ActiveRecord::Base
acts_as_cornerstone_user :auth_with => Proc.new { |controller| controller.current_user }
end
You can then use the current_cornerstone_user
helper to get the current authenticated user.
This method breaks when acts_as_cornerstone_user
is used on multiple classes. But you then have the problem of having multiple cornerstone users without knowing anything about the application models (you're supposed to be in your gem).
Update
If you'd like to have a syntax like :auth_with => :warden
, you could replace the helper with the following :
module Cornerstone
module CornerStoneHelper
def current_cornerstone_user
if Config.auth_with.respond_to?(:call)
Config.auth_with.call(controller)
elsif Config::AUTH_MODES.keys.include?(Config.auth_with)
Config::AUTH_MODES[Config.auth_with].call(controller)
end
end
end
end
with Cornerstone::Config::AUTH_MODES
set up like this :
module Cornerstone
class Config
AUTH_MODES = {
:warden => Proc.new { |controller| controller.env['warden'].user },
:devise => Proc.new { |controller| controller.current_user }
}
end
end
精彩评论