在特定控制器方法上切换 "ActionController::Parameters.action_on_unpermitted_parameters = :raise"?

Toggle "ActionController::Parameters.action_on_unpermitted_parameters = :raise" on specific controller methods?

我想用

ActionController::Parameters.action_on_unpermitted_parameters = :raise

为了引发异常,传入了未经允许的参数,但我只想在特定的控制器方法上执行此操作,而不是在 /config/ 中设置它并将其应用于整个环境。有什么办法吗?

更新:(从迈克的回答中汲取灵感)

要限制仅对一组控制器操作进行更改并将其恢复为调用操作之前 class 属性所持有的原始值,我们可以使用 around_action

class SomeController < ApplicationController
  around_action :raise_action_on_unpermitted_parameters, only: %i[create update]

  def index
    # ...
  end

  def create
    # ...
  end

  def update
    # ...
  end

  private

  def raise_action_on_unpermitted_parameters
    original = ActionController::Parameters.action_on_unpermitted_parameters
    ActionController::Parameters.action_on_unpermitted_parameters = :raise
    yield
  ensure
    ActionController::Parameters.action_on_unpermitted_parameters = original
  end
end

我不确定 Wasif 的回答是否能正常工作,因为它永远不会恢复原状。至少我认为你想要这个:

class SomeController < ApplicationController
  around_action :raise_action_on_unpermitted_parameters, only: %i[create update]

  def index
    # ...
  end

  def create
    # ...
  end

  def update
    # ...
  end

  private

  def raise_action_on_unpermitted_parameters
    begin
      ActionController::Parameters.action_on_unpermitted_parameters = :raise
      yield
    ensure
      ActionController::Parameters.action_on_unpermitted_parameters = :log
    end
  end
end

即便如此,如果您使用像 Puma 这样的多线程服务器,我也不确定您是否会遇到设置为在不同的控制器操作上意外引发的竞争条件。

您可以创建自己的参数class:

  class Parameters < ActionController::Parameters
    self.action_on_unpermitted_parameters = :raise
  end

  def params
    Parameters.new(super.to_unsafe_hash)
  end

这依赖于 Rails 的当前实施来检查 self.class.action_on_unpermitted_parameters 以确定要做什么。

与在操作期间切换 ActionController::Parameters.action_on_unpermitted_parameters 相比,我更喜欢此解决方案,因为您可以控制自定义行为的位置。其他代码不受影响。但这取决于您的需求。您想要提升行为 during 一些 controller action 还是 within controller action code?