1

我正在构建一个使用“充当”格式的 Rails 引擎来建立与父应用程序的用户模型的关系。

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.

4

1 回答 1

2

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
于 2011-08-07T16:05:57.600 回答