Rails 4 - Parámetros fuertes-Objetos Anidados


Tengo una pregunta bastante simple. Pero no he encontrado una solución hasta ahora.

Así que aquí está la cadena JSON que envío al servidor:

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

Usando el nuevo método de permiso, tengo:

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

Esto no genera errores, pero la entrada de la base de datos creada contiene null en lugar del valor groundtruth.

Si acabo de establecer:

params.require(:measurement).permit!

Todo se guarda como se esperaba, pero por supuesto, esto mata la seguridad proporcionada por los parámetros fuertes.

He encontrado soluciones, cómo permitir arrays, pero no un solo ejemplo usando objetos anidados. Esto debe ser posible de alguna manera, ya que debería ser un caso de uso bastante común. Entonces, ¿cómo funciona?

Author: Benjamin M, 2013-08-26

3 answers

Por extraño que suene cuando desea permitir atributos anidados, especifique los atributos del objeto anidado dentro de una matriz. En su caso sería

Actualización como sugiere @RafaelOliveira

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

Por otro lado, si desea anidados de varios objetos, entonces lo envuelve dentro de un hash {así

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


Rails en realidad tienen bastante buena documentación sobre esto: http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit

Para mayor clarificación, usted podría mirar la implementación de permit y strong_parameters en sí: https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247

 161
Author: j03w,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-26 15:11:23

Encontré esta sugerencia útil en mi caso:

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

Revisa este enlace del comentario de Xavier en github.

Este enfoque pone en lista blanca todo el objeto params[:measurement][:groundtruth].

Usando los atributos de las preguntas originales:

  def product_params
    params.require(:measurement).permit(:name, :groundtruth).tap do |whitelisted|
      whitelisted[:groundtruth] = params[:measurement][:groundtruth]
    end
  end
 19
Author: M.ElSaka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-20 00:39:21

Permitiendo un objeto anidado :

params.permit( {:school => [:id , :name]}, 
               {:student => [:id, 
                            :name, 
                            :address, 
                            :city]},
                {:records => [:marks, :subject]})
 5
Author: Codiee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-15 12:29:04