web-dev-qa-db-fra.com

Rails 4 - Paramètres forts - Objets imbriqués

J'ai une question assez simple. Mais n'avons pas trouvé de solution jusqu'à présent.

Alors voici la chaîne JSON que j’envoie au serveur:

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

En utilisant la nouvelle méthode de permis, j'ai:

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

Cela ne génère aucune erreur, mais l'entrée de base de données créée contient null au lieu de la valeur groundtruth.

Si je viens de définir:

params.require(:measurement).permit!

Tout est sauvegardé comme prévu, mais bien sûr, cela tue la sécurité fournie par des paramètres puissants.

J'ai trouvé des solutions, comment autoriser les tableaux, mais pas un seul exemple utilisant des objets imbriqués. Cela doit être possible en quelque sorte, car ce devrait être un cas d'utilisation assez courant. Alors, comment ça marche?

126
Benjamin M

Aussi étrange que cela puisse paraître lorsque vous souhaitez autoriser des attributs imbriqués, vous spécifiez les attributs d'un objet imbriqué dans un tableau. Dans votre cas ce serait

Update comme suggéré par @RafaelOliveira

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

D'autre part, si vous voulez imbriquer plusieurs objets, vous l'enroulez dans un hachage… comme ceci

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


Les rails ont en fait une assez bonne documentation à ce sujet: http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit

Pour plus de précisions, vous pouvez examiner l’application de permit et strong_parameters lui-même: https://github.com/Rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247

165
j03w

J'ai trouvé cette suggestion utile dans mon cas:

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

Vérifiez ce lien du commentaire de Xavier sur github.

Cette approche liste blanche l’ensemble de l’objet params [: mesure] [: groundtruth].

Utilisation des attributs de questions d'origine:

  def product_params
    params.require(:measurement).permit(:name, :groundtruth).tap do |whitelisted|
      whitelisted[:groundtruth] = params[:measurement][:groundtruth]
    end
  end
20
M.ElSaka

Autoriser un objet imbriqué:

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

Si c'est Rails 5, à cause de la nouvelle notation de hachage: params.permit(:name, groundtruth: [:type, coordinates:[]]) fonctionnera correctement.

0
user8164115