2011-07-27 177 views
1

我正在構建一個使用「作爲」格式與父應用程序的用戶模型建立關係的Rails引擎。如何從Rails 3.1引擎調用父應用程序的輔助方法

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

你需要一個或多個基礎用戶嗎? (即一個授權方法或每個類的一個) –

+0

另外,身份驗證應該是控制器的工作。你需要認證的用戶在哪裏? –

+0

在引擎自己的控制器中需要經過身份驗證的用戶,但身份驗證發生在父應用程序中。 – astjohn

回答

2

像這樣的事情應該工作,只要你有你的應用程序中定義只有一個基石用戶:(即app/helpers/cornerstone_helper.rb

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 

然後在你的寶石定義一個幫手:

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 
+0

謝謝!我會試試,但如果有多個用戶類,我會想怎麼辦?例如,一個從User類繼承的Admin類或類似的東西......我試圖使引擎儘可能靈活。調用父應用程序中定義的current_user方法是我能想到的最好的方法。理想情況下,我想使用上面概述的PLUS:auth_with =>:warden。監獄的案件要容易得多。 – astjohn

+0

我更新了我的答案,這是你的想法? –

+0

我剛剛找到一些時間來嘗試您的解決方案。不幸的是,我不認爲在模型中指定Proc會起作用,因爲模型不能訪問控制器對象。源代碼在github上,如果你想仔細看看... https:// github。com/astjohn /基石 – astjohn

相關問題