首页 > 解决方案 > 如何在 Rails 5.2 中允许哈希数组

问题描述

我正在尝试通过发布来创建多个“缺席”:

Parameters: {"absences"=>[{"user_id"=>1, "lesson_id"=>25,
"excused"=>true}, {"user_id"=>2, "lesson_id"=>25, "excused"=>true}]}

但是,我无法在控制器中将此格式列入白名单。我尝试遵循“如何在 Rails 中对对象数组使用强参数”中的解决方案。

就我而言:

def absence_params
  params.permit(absences: [:user_id, :lesson_id, :excused])
end

我明白了

ActiveModel::UnknownAttributeError (unknown attribute 'absences' for Absence.):

然后我尝试了:

Parameters: {"absence"=>[{"user_id"=>1, "lesson_id"=>25,
"excused"=>true}, {"user_id"=>2, "lesson_id"=>25, "excused"=>true}]}

def absence_params
  params.permit(:absence, array: [:user_id, :lesson_id, :excused])
end

并得到:

Unpermitted parameters: :absence, :format

---- 已解决 ----

  1. gem 'cancancan' 不允许我使用数组创建。
  2. 如果您在允许强参数中的数组时遇到问题,请尝试

params.require(:absences).map do |p|
  p.permit(:user_id, :lesson_id, :excused)
end

标签: ruby-on-railsruby

解决方案


您的参数许可代码是正确的:

require "bundler/inline"

gemfile(ENV['INSTALL'] == '1') do
  source "https://rubygems.org"
  gem "actionpack", "6.0.2.2"
  gem "activesupport", "6.0.2.2"
end

require "active_support/core_ext"
require "action_controller/metal/strong_parameters"
require "minitest/autorun"


class BugTest < Minitest::Test
  def test_stuff

    params = ActionController::Parameters.new({
      "absences"=>[
        {"user_id"=>1, "unpermitted_param" => 123, "lesson_id"=>25, "excused"=>true},
        {"user_id"=>2, "lesson_id"=>25, "excused"=>true}
      ]
    })

    assert_equal(
      {
        "absences"=>[
          {"user_id"=>1, "lesson_id"=>25, "excused"=>true},
          {"user_id"=>2, "lesson_id"=>25, "excused"=>true}
        ]
      },
      params.permit(absences: [:user_id, :lesson_id, :excused]).to_h
    )
  end
end

该错误来自其他地方,很可能您正在尝试执行类似的操作Absence.create(absence_params),这仅适用于单个记录。

要立即创建一个数组,您应该相应地调整其他相关代码,例如:

  1. 手动处理数组,如:

    @absenses = params["absences"].map do |raw_absense_params|
      Absense.create!(raw_absense_params.permit(:user_id, :lesson_id, :excused))
    end
    
  2. 如果您有任何(可能) ,请为父accepts_nested_attrubutes_for :absenses模型雇用。Lesson这样做的代码会更简洁,因为 Rails 会为您处理大部分事情,例如由于验证而并非所有实例都可以保存的情况等。


推荐阅读