Рельсы 4 - Сильный Параметров Вложенных Объектов


у меня есть довольно простой вопрос. Но до сих пор не нашли решения.

Итак, вот строка JSON, которую я отправляю на сервер:

{
  "name" : "abc",
  "groundtruth" : {
    "type" : "Point",
    "coordinates" : [ 2.4, 6 ]
  }
}

используя новый метод разрешения, я получил:

params.require(:measurement).permit(:name, :groundtruth)

это не вызывает ошибок, но созданная запись базы данных содержит null вместо значения groundtruth.

Я:

params.require(:measurement).permit!

все get сохраняется, как ожидалось, но, конечно, это убивает безопасность, предоставляемую сильные параметры.

Я нашел решения, как разрешить массивы, но ни одного примера с использованием вложенных объектов. Это должно быть возможно как-то, так как это должно быть довольно распространенным случаем использования. Итак, как это работает?

3 123

3 ответа:

как бы странно это ни звучало, когда вы хотите разрешить вложенные атрибуты, вы указываете атрибуты вложенного объекта в массиве. В вашем случае это было бы

обновление как предложил @RafaelOliveira

params.require(:measurement)
      .permit(:name, :groundtruth => [:type, :coordinates => []])

С другой стороны, если вы хотите вложенные из нескольких объектов, то вы обернуть его в хэш... как это

params.require(:foo).permit(:bar, {:baz => [:x, :y]})


рельсы на самом деле имеют довольно хорошую документацию по этому вопросу: 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

проверить это ссылке из комментария Ксавье на 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]})