Rails 5: impossible de récupérer les valeurs de hachage du paramètre

Je rencontre un problème étrange.

undefined method `values' for #<ActionController::Parameters:0x007fb06f6b2728>

Est l'erreur que je reçois, quand j'attribue une variable à un hachage param, et essaie d'obtenir ses valeurs.

attributes = params[:line_item][:line_item_attributes_attributes] || {}
attributes.values

Le paramètre ressemble à ceci un hachage de hachages:

{"0"=>{"product_attribute_id"=>"4"}, "1"=>{"product_attribute_id"=>"7"}}

Maintenant, quand je fais cela dans la console et que je l'attribue à une variable, cela fonctionne parfaitement. J'ai donc du mal à comprendre ce qui ne fonctionne pas ici-et comment le faire fonctionner.

21
demandé sur SsouLlesS 2016-01-22 17:52:11

4 réponses

Jetez un oeil à Ce . Très bizarre puisque ActionController::Parameters est une sous-classe de Hash, vous pouvez le convertir directement en un hash en utilisant la méthode to_h sur le hash params.

Cependant {[9] } ne fonctionnera qu'avec les paramètres de la liste blanche, vous pouvez donc faire quelque chose comme:

permitted = params.require(:line_item).permit(: line_item_attributes_attributes)
attributes = permitted.to_h || {}
attributes.values

Mais si vous ne voulez pas de liste blanche, il vous suffit d'utiliser la méthode to_unsafe_h.

Mise à jour

J'étais très curieux de ce problème, alors j'ai commencé à faire des recherches, et maintenant que vous clarifié que vous utilisez Rails 5, Eh bien c'est la cause de ce problème, comme l'a dit @tillmo dans les versions stables de Rails comme 4.x, ActionController::Parameters est une sous-classe de Hash, donc il devrait en effet répondre à la méthode values, cependant dans Rails 5 ActionController::Parameters retourne maintenant un objet au lieu d'un Hash

Note : cela n'affecte pas l'accès aux clés dans le hash params comme params[:id]. Vous pouvez afficher la requête Pull {[27] } qui a implémenté cette modification.

Pour accéder aux paramètres dans l'objet, vous pouvez ajouter to_h les paramètres:

params.to_h

Si nous regardons la méthode to_h dans ActionController::Parameters, nous pouvons voir qu'elle vérifie si les paramètres sont autorisés avant de les convertir en hachage.

# actionpack/lib/action_controller/metal/strong_parameters.rb
def to_h
  if permitted?
    @parameters.to_h
  else
    slice(*self.class.always_permitted_parameters).permit!.to_h
  end
end

, Par exemple exemple

def do_something_with_params
  params.slice(:param_1, :param_2)
end

Qui retournerait:

{ :param_1 => "a", :param_2 => "2" }

Mais maintenant cela retournera un objet ActionController::Parameters.

Appeler to_h sur ceci retournerait un hachage vide car param_1 et param_2 ne sont pas autorisés.

Pour accéder au params à partir de ActionController::Parameters, vous devez d'abord autoriser les paramètres, puis appel de to_h sur l'objet

def do_something_with_params
  params.permit([:param_1, :param_2]).to_h
end

Ce qui précède retournerait un hachage avec les paramètres que vous venez d'Autoriser, mais si vous ne voulez pas autoriser les paramètres et que vous voulez ignorer cette étape, il existe une autre méthode en utilisant to_unsafe_hash méthode:

def do_something_with_params
  params.to_unsafe_h.slice(:param_1, :param_2)
end

Il existe un moyen de Toujours autoriser les paramètres d'une configuration à partir d'une application.rb, si vous voulez toujours autoriser certains paramètres, vous pouvez définir une option de configuration. Remarque: cela reviendra le hachage avec des clés de chaîne, pas des clés de symbole.

#controller and action are parameters that are always permitter by default, but you need to add it in this config.
config.always_permitted_parameters = %w( controller action param_1 param_2)

Maintenant, vous pouvez accéder aux paramètres comme:

def do_something_with_params
  params.slice("param_1", "param_2").to_h
end

Notez que maintenant les clés sont des chaînes et non des symboles.

J'espère que cela vous aidera à comprendre la racine de votre problème.

Source: eileen.codes

35
répondu SsouLlesS 2016-01-23 02:13:56

Puisque dans Rails 5 paramètres sont de la classe 'ActionController:: Parameters'

Si vous faites params. to_h, vous obtiendrez l'erreur suivante.

*** ActionController::UnfilteredParameters Exception: unable to convert 
unpermitted parameters to hash

Vous pouvez faire comme suit pour obtenir les paramètres au format de hachage:

parameters = params.permit(params.keys).to_h
5
répondu Abhi 2017-08-24 11:28:28

Je pense que ce qui se passe est le suivant:

Dans une console, vous travaillez avec un hachage simple appelé attributes. En tant que hachage, le paramètre attributes dans la console a une méthode d'instance valide appelée values.

Dans votre application rails, le hachage params n'est plus un simple hachage. C'est une instance de la classe ActionController::Parameters. Comme une instance de cette classe, il ne dispose pas d'une méthode d'instance appelée values, mais il a de une méthode d'instance appelée to_h & to_unsafe_h, qui permettrait d'atteindre vos objectifs. Après avoir appelé to_h sur vos paramètres, vous pouvez appeler la méthode values.

1
répondu BigRon 2016-01-22 16:12:04

Word to the wise: si vous utilisez link_to_sorted de la gemme triée , elle brise les vues dans Rails 5.

0
répondu CD-RUM 2017-08-11 19:46:34