设计 - 覆盖ParameterSanitizer

时间:2018-01-07 20:49:07

标签: ruby-on-rails devise

我正在尝试按照以下说明为每个型号配置不同的Devise强参数消毒剂; https://github.com/plataformatec/devise#strong-parameters

我在Employer模型目录中创建了一个名为parameter_sanitizer的新文件;

应用程序/控制器/雇主/ paramater_sanitizer.rb

class Employer::ParameterSanitizer < Devise::ParameterSanitizer
  def initialize(*)
    super
    devise_parameter_sanitizer.permit(:sign_up, keys: [:forename, :surname, :username)
  end
end

在我的应用程序控制器中,我有;

    require 'employers/parameter_sanitizer'

    class ApplicationController < ActionController::Base
          before_filter :devise_parameter_sanitizer, if: :devise_controller?
          protect_from_forgery with: :exception

          protected

          def devise_parameter_sanitizer
            if resource_class == Employer
              Employer::ParameterSanitizer.new(Employer, :employer, params)
            else
              super # Use the default one
            end
          end
    end

我从注册雇主对象获得的错误是;

Devise中的NameError :: ConfirmationsController #show 未定义的局部变量或方法`devise_parameter_sanitizer&#39;对于#

关于如何克服这个问题的任何建议?

谢谢, 标记

1 个答案:

答案 0 :(得分:0)

在此initialize方法中,您将params保存为实例变量@params,因此在您的方法中应该执行以下操作:

class Employer::ParameterSanitizer < Devise::ParameterSanitizer
  def initialize(*)
    super
    @params.permit(:sign_up, keys: [:forename, :surname, :username])
  end

我相信这应该可以在不指定@params

的情况下工作

说明

要找到此问题的解决方案,请检查devise api以更好地了解您调用的方法并阅读`Devise::ParameterSanitizer源代码

我引用他们关于#permit() method

的ruby-rocs
  

实例方法详细信息

#permit(action, keys: nil, except: nil, &block) ⇒ Object
  

在允许的操作列表中添加或删除新参数。

     

参数   action - 包含控制器正在执行的操作的符号,例如sign_upsign_in等。

     

keys: - 也应该允许的一组键。

     

except: - 不允许使用的一组键。

     

block - 应该用于允许操作参数而不是基于数组的方法的块。将使用ActionController::Parameters实例调用该块。

     

实施例

# Adding new parameters to be permitted in the `sign_up` action.

devise_parameter_sanitizer.permit(:sign_up, keys: [:subscribe_newsletter])

# Removing the `password` parameter from the `account_update` action.
devise_parameter_sanitizer.permit(:account_update, except: [:password])

# Using the block form to completely override how we permit the
# parameters for the `sign_up` action.
devise_parameter_sanitizer.permit(:sign_up) do |user|
  user.permit(:email, :password, :password_confirmation)
end
  

什么都不返回。

我也引用

  

如果您有多个Devise模型,则可能需要为每个模型设置不同的参数消毒剂。在这种情况下,我们建议继承Devise :: ParameterSanitizer并添加您自己的逻辑:

class ApplicationController < ActionController::Base
  protected

  def devise_parameter_sanitizer
    if resource_class == User
      User::ParameterSanitizer.new(User, :user, params)
    else
      super # Use the default one
    end
  end
end

User::ParameterSanitizer.new(User, :user, params)会从parameter_sanitizer.rb source code

调用此初始化方法
def initialize(resource_class, resource_name, params)
   @auth_keys      = extract_auth_keys(resource_class)
   @params         = params
   @resource_name  = resource_name
   @permitted      = {}

   DEFAULT_PERMITTED_ATTRIBUTES.each_pair do |action, keys|
     permit(action, keys: keys)
   end
end

所以基本上你正在调用initialize(User, :user, params),我不明白为什么设计在这种方法中接受params,因为它有自己的方式通过保存允许字段的静态哈希来允许属性。

DEFAULT_PERMITTED_ATTRIBUTES = {
   sign_in: [:password, :remember_me],
   sign_up: [:password, :password_confirmation],
   account_update: [:password, :password_confirmation, :current_password]
}

并允许他们循环

DEFAULT_PERMITTED_ATTRIBUTES.each_pair do |action, keys|
   permit(action, keys: keys)
end

在此initialize方法中,您将params保存为实例变量@params,因此在您的方法中应该执行以下操作:

class Employer::ParameterSanitizer < Devise::ParameterSanitizer
  def initialize(*)
    super
    @params.permit(:sign_up, keys: [:forename, :surname, :username])
  end