【问题标题】:Toggle "ActionController::Parameters.action_on_unpermitted_parameters = :raise" on specific controller methods?在特定控制器方法上切换“ActionController::Parameters.action_on_unpermitted_pa​​rameters = :raise”?
【发布时间】:2017-12-07 10:44:13
【问题描述】:

我想用

ActionController::Parameters.action_on_unpermitted_parameters = :raise

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

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-5 strong-parameters


    【解决方案1】:

    我不确定 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 这样的多线程服务器,我也不确定您是否会遇到设置为意外触发不同控制器操作的竞争条件。

    【讨论】:

      【解决方案2】:

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

        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_pa​​rameters 相比,我更喜欢此解决方案,因为您可以控制您想要自定义行为的位置。其他代码不受影响。但这取决于您的需求。您是否想要某些控制器动作或控制器动作代码中的提升行为?

      【讨论】:

        【解决方案3】:

        更新:(从 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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-18
          • 1970-01-01
          相关资源
          最近更新 更多