【发布时间】:2017-12-07 10:44:13
【问题描述】:
我想用
ActionController::Parameters.action_on_unpermitted_parameters = :raise
为了引发异常,传入了未经允许的参数,但我只想在特定的控制器方法上执行此操作,而不是将其设置在 /config/ 中并将其应用于整个环境。有什么办法吗?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-5 strong-parameters
我想用
ActionController::Parameters.action_on_unpermitted_parameters = :raise
为了引发异常,传入了未经允许的参数,但我只想在特定的控制器方法上执行此操作,而不是将其设置在 /config/ 中并将其应用于整个环境。有什么办法吗?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-5 strong-parameters
我不确定 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 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 相比,我更喜欢此解决方案,因为您可以控制您想要自定义行为的位置。其他代码不受影响。但这取决于您的需求。您是否想要在某些控制器动作或在控制器动作代码中的提升行为?
【讨论】:
更新:(从 Mike 的回答中汲取灵感)
要限制仅针对一组控制器操作的更改并将其恢复为调用操作之前类属性所持有的原始值,我们可以使用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
【讨论】: