Rails 4 - строгие параметры - вложенные объекты

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

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

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

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

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

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

Если бы я просто установил:

params.require(:measurement).permit!

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

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


person Benjamin M    schedule 26.08.2013    source источник
comment
взгляните на этот stackoverflow.com/questions/14483963/   -  person Rajarshi Das    schedule 26.08.2013
comment
@vinodadhikary Это было правильно ... Я думаю, что OP сбит с толку. Как ни странно это звучит, когда вы хотите разрешить вложенные атрибуты, вы все же указываете атрибуты вложенного объекта в массиве. С другой стороны, если вы хотите вложить несколько объектов, вы помещаете их в хэш… см. api.rubyonrails.org/classes/ActionController/ и github.com/rails/rails/blob/master/actionpack/lib/   -  person j03w    schedule 26.08.2013


Ответы (4)


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

Обновить, как предлагает @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

person j03w    schedule 26.08.2013
comment
оба случая в этом ответе одинаковы, просто фигурные скобки вокруг {: groundtruth = ›[...]} не обязательны; Это хэш, но интерпретатор может определить, где начинается и заканчивается хеш, без явных фигурных скобок. - person speakingcode; 21.03.2014
comment
Вложенные массивы атрибутов не допускают вложенных атрибутов. Вложенные атрибуты и attr_accessor указаны в моем приложении как недопустимые параметры. Все еще ищем безопасное решение. - person Katarzyna; 20.08.2015
comment
В случае нескольких вложенных объектов вы также должны разрешить идентификатор, чтобы это работало. Дополнительная информация здесь: stackoverflow.com/questions/18308714/ < / а> - person Fabrice Carrega; 13.05.2016
comment
Это разрешает только ОДИН набор вложенных атрибутов. Это не сработает в случае от одного ко многим. - person AKWF; 10.03.2018
comment
@speakingcode, если это так, я подозреваю, что лучше оставить фигурные скобки, чтобы читатель кода лучше понимал, что происходит - person stevec; 23.08.2020

Я нашел это предложение полезным в моем случае:

  def product_params
    params.require(:product).permit(:name).tap do |whitelisted|
      whitelisted[:data] = params[:product][:data]
    end
  end

Проверьте эту ссылку комментария Ксавьера на github.

Этот подход помещает в белый список весь объект params [: measure] [: groundtruth].

Используя исходные атрибуты вопросов:

  def product_params
    params.require(:measurement).permit(:name, :groundtruth).tap do |whitelisted|
      whitelisted[:groundtruth] = params[:measurement][:groundtruth]
    end
  end
person M.ElSaka    schedule 29.06.2014
comment
Просто примечание: это все равно будет отображаться в журнале как недопустимые параметры, но модель все равно их примет. - person Weston Ganger; 25.01.2016
comment
Не уверен в Rails 4, но в моем проекте Rails 5 я должен вызвать permit!, чтобы он был добавлен в белый список, иначе он остался неразрешенным после нажатия на него. В этом случае это будет params[:measurement][:groundtruth].permit! - person nayiaw; 22.02.2017
comment
@nayiaw, я также получаю недопустимое сообщение, но добавление permit! вызывает эту ошибку NoMethodError (undefined method permit! ' для # ‹Массив: 0x007f80cb71ea00›): ` - person wuliwong; 18.04.2018
comment
Метод @wuliwong permit! недоступен в Array. Вам потребуется доступ к соответствующему экземпляру класса, чтобы иметь доступ к permit! (давно я забыл имя класса, но это что-то вроде ActionController::Parameters на основе эта страница). - person nayiaw; 18.04.2018

Разрешение вложенного объекта:

params.permit( {:school => [:id , :name]}, 
               {:student => [:id, 
                            :name, 
                            :address, 
                            :city]},
                {:records => [:marks, :subject]})
person Codiee    schedule 30.03.2016

Если это Rails 5, из-за новой хэш-записи: params.permit(:name, groundtruth: [:type, coordinates:[]]) будет работать нормально.

person user8164115    schedule 01.11.2018