У меня довольно простой вопрос. Но до сих пор не нашел решения.
Вот строка JSON, которую я отправляю на сервер:
{
"name" : "abc",
"groundtruth" : {
"type" : "Point",
"coordinates" : [ 2.4, 6 ]
}
}
Используя новый метод разрешения, я'получил:
params.require(:measurement).permit(:name, :groundtruth)
Это не вызывает ошибок, но созданная запись базы данных содержит null
вместо значения groundtruth.
Если я просто установлю:
params.require(:measurement).permit!
Все будет сохранено, как и ожидалось, но, конечно, это убивает безопасность, обеспечиваемую сильными параметрами.
Я'нашел решения, как разрешить массивы, но ни одного примера с использованием вложенных объектов. Это должно быть как-то возможно, поскольку это должно быть довольно распространенным случаем использования. Итак, как это работает?
Как бы странно это ни звучало, когда вы хотите разрешить вложенные атрибуты, вы указываете атрибуты вложенного объекта в массиве. В вашем случае это будет
Обновить, как предложил @RafaelOliveira
params.require(:measurement)
.permit(:name, :groundtruth => [:type, :coordinates => []])
С другой стороны, если вы хотите вложить несколько объектов, то оберните их внутри хэша... вот так
params.require(:foo).permit(:bar, {:baz => [:x, :y]})
На самом деле в Rails есть довольно хорошая документация по этому вопросу: http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit
Для дальнейшего разъяснения вы можете посмотреть на саму реализацию permit
и strong_parameters
: https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247.
Я нашел это предложение полезным в моем случае:
def product_params
params.require(:product).permit(:name).tap do |whitelisted|
whitelisted[:data] = params[:product][:data]
end
end
Проверьте этот ссылка комментарий Xavier'a на github.
Этот подход позволяет внести в белый список весь объект params[:measurement][:groundtruth].
Используя атрибуты исходных вопросов:
def product_params
params.require(:measurement).permit(:name, :groundtruth).tap do |whitelisted|
whitelisted[:groundtruth] = params[:measurement][:groundtruth]
end
end
Разрешение вложенного объекта:
params.permit( {:school => [:id , :name]},
{:student => [:id,
:name,
:address,
:city]},
{:records => [:marks, :subject]})
Если это рельсы 5, из-за новой хэш-нотации:
параметры.разрешение(:имя, groundtruth: [:тип, координаты:[]])
будет работать нормально.