Сильные параметры с вложенным хешем
У меня есть следующие параметры и я не могу получить сильные параметры для работы.
Вот мой основной код, для простоты запускаемый в консоли 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]])
что действительно боль в заднице.