Ruby:从单独的文件向模块添加方法并自动加载它

时间:2012-04-29 21:05:46

标签: ruby ruby-on-rails-3

我在rails应用程序中使用了Sorcery库。其中一个模块用于外部身份验证,我需要为该模块添加一个方法。

现有代码为here,我想在this patch添加add_provider_to_user方法。

所以,我在我的lib/modules目录中添加了一个文件,我告诉他们要自动加载。该文件名为sorcery_extension.rb,它看起来像这样:

module Sorcery
  module Controller
    module Submodules
      module External
        module InstanceMethods
          protected

          # If user is logged, he can add all available providers into his account
          def add_provider_to_user(provider)
            provider_name = provider.to_sym
            provider = Config.send(provider_name)
            user_hash = provider.get_user_hash
            config = user_class.sorcery_config

            user = current_user.send(config.authentications_class.to_s.downcase.pluralize).build(config.provider_uid_attribute_name => user_hash[:uid], config.provider_attribute_name => provider)
            user.save(:validate => false)

            return user
          end
        end
      end
    end
  end
end

这不起作用。我在我的控制器中得到undefined method error(调用其他巫术方法可以正常工作)。

所以,我对ruby的基本理解是你可以随时向对象或模块添加方法......我想我已经在文件中正确地复制了模块的嵌套。我是否需要将模块文件命名为不同的名称?我不太确定如何做这种事情,所以任何帮助都非常感激。谢谢!

2 个答案:

答案 0 :(得分:1)

您的文件永远不会require d。您可以通过在控制台中输入来仔细检查:

Sorcery::Controller::Submodules::External::InstanceMethods.method_defined?(:add_provider_to_user)
  # => will return false, you want true

原因是只有当一个常量未知时才会发生故障,Rails会尝试从不同的自动加载路径中自动加载它。

您必须明确要求您的文件(例如,来自初始化程序中的文件)并且事情将按预期工作。

答案 1 :(得分:1)

Rails约定要求是对于每个模块,它在同名目录中查找。

为您的例子

module Sorcery
  module Controller
    module Submodules
      module External
       module InstanceMethods

如果要将模块放在lib目录中。当它转到“autorequire”时,Rails会期望它在这条路径中

lib/sorcery/controller/submodules/external/instance_methods.rb

这就是保持模块嵌套浅的一般好习惯。 ~2级深。