如何从ActionController :: Parameters中删除对象?

时间:2017-10-09 18:31:44

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

我试图从我的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然后编辑并传递 - 它可以工作。但是,如果可以使用实际的原始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

3 个答案:

答案 0 :(得分:1)

允许params创建一个新对象:

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)

或者,通过使用memoization:

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>

答案 1 :(得分:0)

只需使用Hash#except代替#extract!

  

除了(*键)

     

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

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

答案 2 :(得分:0)

这对我有用:

params.except(:password)