简体   繁体   中英

How to permit array of hashes in Rails 5.2

I am trying to create multiple "Absence"s by posting:

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

However, I am not able to whitelist this format in the controller. I attempted to follow the solution from " How to use strong parameters with an objects array in Rails ".

In my case:

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

I get

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

Then I tried:

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

and got:

Unpermitted parameters: :absence, :format

---- Resolved ----

  1. The gem 'cancancan' was not allowing me to create using an array.
  2. If you have an issue permitting an array in the strong params, try

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

Your parameters permit code is correct:

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

The error comes from some other place, most likely you're trying to do something like Absence.create(absence_params) , which will only work for single records.

To create an array at once you should adjust other relevant code accordingly, for example:

  1. Manually handle the array like:

     @absenses = params["absences"].map do |raw_absense_params| Absense.create!(raw_absense_params.permit(:user_id, :lesson_id, :excused)) end
  2. Employ accepts_nested_attrubutes_for :absenses for the parent model if you have any (probably Lesson ). The code for this will be cleaner, as Rails will handle most things for you, like cases when not all instances can be saved because of validation, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM