【问题标题】:How can I remove objects from ActionController::Parameters?如何从 ActionController::Parameters 中删除对象?
【发布时间】:2018-03-21 01:00:45
【问题描述】:

我试图从我的 ActionController::Parameters 对象中删除一个元素,但它没有按我的预期工作。我的report_params对象如下,

<ActionController::Parameters {"id"=>"51956915", "author_id"=>"1", "workout_attributes"=><ActionController::Parameters {"player_id"=>"14155", "date"=>"2017-10-09", "report_id"=>"51956915"} permitted: true> permitted: true>

我想执行以下操作以从对象中删除workout_attributes

report_params.extract!(:workout_attributes)

这会返回下面的信息,但是当我重新运行report_params时它仍然存在

<ActionController::Parameters {"player_id"=>"14155", "date"=>"2017-10-09", "report_id"=>"51956915"} permitted: true>

当我在控制台中重新运行report_params...

<ActionController::Parameters {"id"=>"51956915", "author_id"=>"1", "workout_attributes"=><ActionController::Parameters {"player_id"=>"14155", "date"=>"2017-10-09", "report_id"=>"51956915"} permitted: true> permitted: true>

更新 这是控制器的 report_params 方法:

def report_params
  params.require(:report).permit(:id, :author_id, 
        workout_attributes: [:player_id, :report_id, :date]
        )
end

那么我是否不允许编辑report_params 对象,我需要制作它的副本,然后将该副本传递给操作中的更新函数?或者这里有什么我做的不对?谢谢!

使用“有效”的解决方案进行更新

我发现如果我执行以下操作,基本上是制作参数的副本,然后编辑并传递 - 它可以工作。但是,如果可以使用实际的原始 params 对象来完成,这似乎是丑陋的代码。

  modified_report_params = report_params
  modified_report_params.extract!(:workout_attributes)

  respond_to do |format|
    format.js do
      if @report.update(modified_report_params)
      # ...
  end

【问题讨论】:

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


    【解决方案1】:

    这对我有用:

    params.except(:password)
    

    【讨论】:

      【解决方案2】:

      只需使用Hash#except 而不是#extract!

      除了(*键)

      返回一个包含除给定键之外的所有内容的哈希。

      respond_to do |format|
        format.js do
          if @report.update(report_params.except(:workout_attributes))
            # ...
          end
        end
      end
      

      【讨论】:

      • ActionController::Parameters 不再继承自 Rails 5 中的 HashWithIndifferentAccess。但是这个类有自己的方法 except,是的。
      【解决方案3】:

      允许参数创建一个新对象:

      params = ActionController::Parameters.new(a: 1, b: 2)
      params.object_id
      #=> 70277626506220
      params.permit(:a, :b).object_id #new object created
      #=> 70277626332020
      

      如您所见,每次调用report_params 时,都会从params 创建一个新对象。要解决您的问题,您可以改变 params 本身:

      params.extract!(:workout_attributes)
      

      或者,通过使用记忆:

      def report_params
        @report_params ||= params
          .require(:report)
          .permit(:id, :author_id, workout_attributes: [:player_id, :report_id, :date])
      end
      report_params.extract!(:workout_attributes)
      #=><ActionController::Parameters {"player_id"=>"14155", "date"=>"2017-10-09", "report_id"=>"51956915"} permitted: true>
      

      【讨论】:

        猜你喜欢
        • 2017-01-19
        • 2021-03-02
        • 1970-01-01
        • 2011-01-12
        • 2017-03-08
        • 1970-01-01
        • 2023-01-16
        • 2021-07-23
        • 2017-01-31
        相关资源
        最近更新 更多