如何覆盖此gem模块中的类变量?

时间:2017-05-26 21:07:17

标签: ruby-on-rails devise

我使用devise_saml_authenticatable gem进行saml身份验证,并希望覆盖@@ saml_default_resource_locator 第105行here上的变量。我只是想添加一个额外的where子句,以便它只查看某种类型的用户。我以前覆盖了宝石方法(但从来没有类变量)在初始化器中做了类似的事情:

RedCloth::Formatters::HTML.send(:include, GemExtensions::RedCloth::Formatters::HTML::Notextile)

但我不知道在这个例子中从哪里开始。任何帮助将不胜感激,谢谢!

2 个答案:

答案 0 :(得分:2)

虽然@chumakoff的回答可以解决问题,但我认为你不必这样做,并且不应该以这种方式修补DeviseSamlAuthenticatable gem。在进行身份验证时,gem主要调用Devise.saml_resource_locator访问器下可配置的块。如果未设置此块,则默认情况下会调用Devise.saml_default_resource_locator块。

所以,我猜你应该只设置saml_resource_locator

Devise.saml_resource_locator = Proc.new do |model, saml_response, auth_value|
  model.where(Devise.saml_default_user_key => auth_value).where(...).first
end

另请参阅某些examples的规格。

答案 1 :(得分:0)

更改类变量非常容易。您可以使用class_variable_set方法。或者您可以打开模块并再次定义变量,或使用instance_eval

将此代码放入初始化程序:

Devise.class_variable_set(
  :@@saml_default_resource_locator,
  Proc.new do |model, saml_response, auth_value|
    # whatever you want
  end
)

或者打开模块并再次定义变量:

module Devise
  @@saml_default_resource_locator = Proc.new do |model, saml_response, auth_value|
    # whatever you want
  end
end

使用instance_eval

Devise.instance_eval do
  @@saml_default_resource_locator = Proc.new do |model, saml_response, auth_value|
    # whatever you want
  end
end