2011-07-27 2 views
1

Je construis un moteur de rails qui utilise le format "agit as" pour établir des relations avec le modèle User de l'application parente.Comment appeler la méthode d'aide d'une application parente à partir d'un rail 3.1 engine

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 

Je voudrais pour un développeur pour être en mesure de spécifier un nom de méthode d'assistance en utilisant l'option :auth_with. L'idée est que le développeur spécifiera une méthode d'assistance dans l'application parente qui retournera l'utilisateur connecté pour cette session.

Ma question est une fois que le développeur a spécifié l'option auth_with, comment puis-je appeler la méthode de cette application parente?

Existe-t-il une meilleure approche pour obtenir l'utilisateur connecté de l'application parent? Je voudrais qu'il soit aussi flexible que possible de sorte qu'il ne dépende pas simplement d'appeler current_user.

+0

Avez-vous besoin d'un ou plusieurs utilisateurs de la pierre angulaire? (c'est-à-dire une méthode d'authentification ou une par classe) –

+0

De plus, l'authentification devrait être le travail d'un contrôleur. Où aurez-vous besoin de l'utilisateur authentifié? –

+0

L'utilisateur authentifié sera nécessaire dans les contrôleurs du moteur, mais l'authentification a lieu dans l'application parente. – astjohn

Répondre

2

Quelque chose comme cela devrait fonctionner, aussi longtemps que vous avez un seul utilisateur pierre angulaire défini dans votre application: (.-À-dire dans 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 

Définissez ensuite une aide dans votre bijou:

module Cornerstone 
    module CornerStoneHelper 
    def current_cornerstone_user 
     Config.auth_with.call(controller) 
    end 
    end 
end 

la méthode acts_as_cornerstone est l'utilisé comme ceci:

class MyUser < ActiveRecord::Base 
    acts_as_cornerstone_user :auth_with => Proc.new { |controller| controller.current_user } 
end 

Vous pouvez ensuite utiliser l'assistant current_cornerstone_user pour obtenir l'utilisateur authentifié actuel.

Cette méthode se casse lorsque acts_as_cornerstone_user est utilisé sur plusieurs classes. Mais vous avez alors le problème d'avoir plusieurs utilisateurs de la pierre angulaire sans rien savoir sur les modèles d'application (vous êtes censé être dans votre gemme).

Mise à jour

Si vous souhaitez avoir une syntaxe comme :auth_with => :warden, vous pouvez remplacer l'aide à ce qui suit:

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 

avec Cornerstone::Config::AUTH_MODES mis en place comme ceci:

module Cornerstone 
    class Config 
    AUTH_MODES = { 
     :warden => Proc.new { |controller| controller.env['warden'].user }, 
     :devise => Proc.new { |controller| controller.current_user } 
    } 
    end 
end 
+0

Merci! Je vais essayer, mais que se passerait-il s'il y a plusieurs classes d'utilisateurs? Par exemple, une classe Admin qui hérite d'une classe User ou quelque chose comme ça ... J'essaie de rendre le moteur aussi flexible que possible. L'appel d'une méthode current_user définie dans l'application parente est la meilleure méthode que je puisse trouver. Idéalement, je voudrais utiliser quelque chose comme ce que vous avez souligné ci-dessus PLUS: auth_with =>: warden. Le cas du gardien est beaucoup plus facile. – astjohn

+0

J'ai mis à jour ma réponse, c'est ce que vous aviez en tête? –

+0

Je viens de trouver le temps d'essayer vos solutions. Malheureusement, je ne pense pas que la spécification de la Proc dans le modèle fonctionnera parce que le modèle n'a pas accès à un objet contrôleur. La source est sur github si vous voulez regarder de plus près ... https: // github.com/astjohn/cornerstone – astjohn

Questions connexes