如何从rails 3.1引擎调用父应用程序的帮助方法

时间:2011-07-27 14:04:11

标签: ruby-on-rails ruby ruby-on-rails-3.1 rails-engines

我正在构建一个使用“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

1 个答案:

答案 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