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