web-dev-qa-db-fra.com

des paramètres forts autorisent tous les attributs des attributs imbriqués

Existe-t-il un moyen dans paramètres forts pour autoriser tous les attributs d'un modèle nested_attributes ? Voici un exemple de code.

class Lever < ActiveRecord::Base
 has_one :lever_benefit
 accepts_nested_attributes_for :lever_benefit
end

class LeverBenefit < ActiveRecord::Base
  # == Schema Information
  #  id          :integer          not null, primary key
  #  lever_id    :integer
  #  explanation :text
end

Pour les paramètres forts du levier, j'écris actuellement ceci

def lever
 params.require(:lever).permit(:name,:lever_benefit_attributes => [:lever_id, :explanation])
end

Existe-t-il un moyen pour les attributs imbriqués je peux écrire pour autoriser tous les attributs sans donner explicitement le nom des attributs comme lever_id Et explanation?

Remarque : Veuillez ne pas confondre avec cette question avec permit! Ou permit(:all) c'est pour permettant tout pour les attributs imbriqués

30
AnkitG

La seule situation que j'ai rencontrée où autoriser des clés arbitraires dans un hachage de paramètres imbriqués me semble raisonnable est lors de l'écriture dans une colonne sérialisée. J'ai réussi à le gérer comme ceci:

class Post
  serialize :options, JSON
end

class PostsController < ApplicationController
  ...

  def post_params
    all_options = params.require(:post)[:options].try(:permit!)
    params.require(:post).permit(:title).merge(:options => all_options)
  end
end

try s'assure que nous n'avons pas besoin des cadeaux d'un :options clé.

53
tfischbach

En fait, il existe un moyen de simplement mettre sur liste blanche tous les paramètres imbriqués.

params.require(:lever).permit(:name).tap do |whitelisted|
  whitelisted[:lever_benefit_attributes ] = params[:lever][:lever_benefit_attributes ]
end

Cette méthode a un avantage sur les autres solutions. Il permet d'autoriser des paramètres profondément imbriqués.

Alors que d'autres solutions comme:

nested_keys = params.require(:lever).fetch(:lever_benefit_attributes, {}).keys
params.require(:lever).permit(:name,:lever_benefit_attributes => nested_keys)

Non.


La source:

https://github.com/Rails/rails/issues/9454#issuecomment-14167664

15

Tout d'abord, assurez-vous que vous voulez vraiment autoriser toutes les valeurs dans un hachage imbriqué. Lire Réponse de Damien MATHIE pour comprendre l'ouverture potentielle de failles de sécurité ...

Si vous avez toujours besoin/souhaitez autoriser toutes les valeurs dans un hachage (il existe des cas d'utilisation parfaitement valides pour cela, par exemple le stockage de métadonnées non structurées fournies par l'utilisateur pour un enregistrement), vous pouvez y parvenir en utilisant les bits de code suivants:

def lever_params
  nested_keys = params.require(:lever).fetch(:lever_benefit_attributes, {}).keys
  params.require(:lever).permit(:name,:lever_benefit_attributes => nested_keys)
end

Remarque: Ceci est très similaire à réponse de tf. mais un peu plus élégant car vous n'obtiendrez aucun Unpermitted parameters: lever_benefit_attributes avertissements/erreurs.

11
severin

essayer

params.require(:lever).permit(:name, leave_benefit_attributes: LeaveBenefit.attribute_names.collect { |att| att.to_sym })
6
seufagner