2

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

现有代码在这里,我想从这个补丁add_provider_to_user中添加方法。

所以,我在我的lib/modules目录中添加了一个文件,我告诉 Rails 自动加载。该文件被调用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​​ 的基本理解是您可以随时向对象或模块添加方法......我想我已经在文件中正确复制了模块的嵌套。我需要将模块文件命名为不同的名称吗?我不太确定如何做这种事情,所以非常感谢任何帮助。谢谢!

4

2 回答 2

1

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

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

原因是 auloading 仅在常量未知时发生,在这种情况下 Rails 会尝试从不同的自动加载路径自动加载它。

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

于 2012-04-30T02:12:25.400 回答
1

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

对于你的例子

module Sorcery
  module Controller
    module Submodules
      module External
       module InstanceMethods

如果要将模块放在 lib 目录中。当它进入“autorequire”时,Rails 会在这条路上期待它

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

这就是为什么保持模块嵌套浅的通常很好的约定。~ 2 级深。

于 2012-04-30T04:11:28.123 回答