Сильные параметры с вложенным хешем

У меня есть следующие параметры и я не могу получить сильные параметры для работы.

Вот мой основной код, для простоты запускаемый в консоли Rails:

json = {
  id: 1,
  answers_attributes: {
    c1: { id: "", content: "Hi" },
    c2: { id: "", content: "Ho" }
  }
}

params = ActionController::Parameters.new(json)

Все, что я прочитал, говорит следующее должно работать, но это только дает мне id и пустой хэш answers_attributes:

params.permit(:id, answers_attributes: [:id, :content])
=> { "id"=>1, "answers_attributes"=>{} }

Если я вместо этого вручную список c1 а также c2 (как показано ниже) это работает, но это действительно глупо, потому что я не знаю, сколько ответов даст пользователь, и это много дублирует:

params.permit(:id, answers_attributes: { c1: [:id, :content], c2: [:id, :content] })
=> {"id"=>1, "answers_attributes"=>{"c1"=>{"id"=>"", "content"=>"Hi"}, "c2"=>{"id"=>"", "content"=>"Ho"}}}

Я пытался заменить c1 а также c2 с 0 а также 1, но я все еще должен вручную поставить 0 а также 1 в моем разрешении заявления.

Как я могу разрешить массив вложенных атрибутов неизвестной длины?

2 ответа

Решение

Это делается с помощью синтаксиса, например:

answers_attributes: [:id, :content]

Проблема заключается в ключах, которые вы используете в answers_attributes, Ожидается, что они будут идентификаторами answers_attributes или в случае новых записей 0,

Их изменение дает ожидаемый результат:

json = {
  id: 1,
  answers_attributes: {
    "1": { id: "", content: "Hi" },
    "2": { id: "", content: "Ho" }
  }
}

params = ActionController::Parameters.new(json)

params.permit(:id, answers_attributes:[:id, :content])
=>  {"id"=>1, "answers_attributes"=>{"1"=>{"id"=>"", "content"=>"Hi"}, "2"=>{"id"=>"", "content"=>"Ho"}}}

Изменить: кажется, что 0 не единственный ключ, я имею в виду, что если у вас есть два new записей. Я использую nested_form, и он, кажется, использует очень длинное случайное число.

Ваш answers_attributes содержит c1 и c2, которые не разрешены. http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

ПУТЬ 1: Вы можете передать вложенные атрибуты в виде массива хэшей.

json = {
  id: 1,
  answers_attributes: [ { id: "", content: "Hi" }, { id: "", content: "Ho" } ]
}

Сейчас params.permit(:id, answers_attributes: [:id, :content]) дает

{"id"=>1, "answers_attributes"=>[{"id"=>"", "content"=>"Hi"}, {"id"=>"", "content"=>"Ho"}]}

ПУТЬ 2: Вы можете передать как хеш хешей, как

json = {
  id: 1,
  answers_attributes: {
    c1: { id: "", content: "Hi" },
    c2: { id: "", content: "Ho" }
  }
}

И WAY 1, и WAY 2 имеют одинаковый эффект на уровне модели. Но permit не позволяет передавать значения, если ключи не указаны явно. Так c1 а также c2 не будет разрешено, если явно не указано, как

params.permit(:id, answers_attributes: [c1: [:id, :content], c2: [:id, :content]])

что действительно боль в заднице.

Другие вопросы по тегам