我正在构建一个使用“act as”格式的rails引擎来与父应用程序的User模型建立关系。
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]
Cornerstone::Config.auth_with.flatten!
end
end
module InstanceMethods
end
end
ActiveRecord::Base.send :include, ActsAsCornerstoneUser
end
我希望开发人员能够使用:auth_with
选项指定帮助方法名称。我们的想法是,开发人员将在父应用程序中指定一个帮助方法,该方法将返回该会话的登录用户。
我的问题是,一旦开发人员指定了auth_with
选项,我该如何调用该父应用程序的方法?
是否有更好的方法来获取父应用程序的登录用户?我希望它尽可能灵活,以便它不依赖于简单地调用current_user
。
答案 0 :(得分:2)
这样的东西就可以了。
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
然后在你的宝石中定义一个帮手(即在app/helpers/cornerstone_helper.rb
中):
module Cornerstone
module CornerStoneHelper
def current_cornerstone_user
Config.auth_with.call(controller)
end
end
end
acts_as_cornerstone
方法的用法如下:
class MyUser < ActiveRecord::Base
acts_as_cornerstone_user :auth_with => Proc.new { |controller| controller.current_user }
end
然后,您可以使用current_cornerstone_user
帮助程序获取当前经过身份验证的用户。
当多个类使用acts_as_cornerstone_user
时,此方法会中断。但是你有一个问题就是拥有多个基石用户而不了解应用程序模型(你应该在你的宝石中)。
<强>更新强>
如果您希望使用:auth_with => :warden
之类的语法,可以使用以下内容替换帮助程序:
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
Cornerstone::Config::AUTH_MODES
设置如下:
module Cornerstone
class Config
AUTH_MODES = {
:warden => Proc.new { |controller| controller.env['warden'].user },
:devise => Proc.new { |controller| controller.current_user }
}
end
end