Je rencontre un problème étrange.
undefined method `values' for #<ActionController::Parameters:0x007fb06f6b2728>
est l'erreur que je reçois lorsque j'attribue une variable à un paramètre hash et que j'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, lorsque 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.
jetez un oeil à this . Très bizarre puisque ActionController::Parameters
est une sous-classe de Hash, vous pouvez le convertir directement en un hachage en utilisant la méthode to_h
sur le hachage params.
Cependant, seul to_h
fonctionnera 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 préférez ne pas ajouter de liste blanche, il vous suffit d'utiliser la méthode to_unsafe_h
.
J'étais très curieux à propos de ce problème, alors j'ai commencé mes recherches et, maintenant que vous avez bien précisé que vous utilisez Rails 5, c'est la cause de ce problème, comme @tillmo l'a dit dans les versions stables de Rails comme 4.x, ActionController::Parameters
est un. sous-classe de Hash, il devrait donc bien répondre à la méthode values
, cependant dans Rails 5 ActionController::Parameters
renvoie désormais un objet au lieu d'un hachage
Note: cela n’affecte pas l’accès aux clés dans le hachage params comme params[:id]
. Vous pouvez voir le Pull Request qui a implémenté cette modification.
Pour accéder aux paramètres de l'objet, vous pouvez ajouter to_h
aux paramètres:
params.to_h
Si nous examinons 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
Ce qui reviendrait:
{ :param_1 => "a", :param_2 => "2" }
Mais maintenant, cela retournera un objet ActionController::Parameters
.
Si vous appelez to_h
, vous obtiendrez un hachage vide car param_1 et param_2 ne sont pas autorisés.
Pour avoir accès aux paramètres à partir de ActionController::Parameters
, vous devez d'abord autoriser les paramètres, puis appeler to_h
sur l'objet.
def do_something_with_params
params.permit([:param_1, :param_2]).to_h
end
La procédure ci-dessus renverrait un hachage avec les paramètres que vous venez d'autoriser, mais si vous ne souhaitez pas autoriser les paramètres et souhaitez ignorer cette étape, il existe un autre moyen d'utiliser la méthode to_unsafe_hash
:
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 depuis une configuration de application.rb. Si vous souhaitez toujours autoriser certains paramètres, vous pouvez définir une option de configuration. Remarque: ceci renverra 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
Depuis dans Rails 5, les 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 Hash:
parameters = params.permit(params.keys).to_h
Mais méfiez-vous de l'utiliser! Vous autorisez tous les paramètres pouvant inclure des paramètres inconnus pouvant nuire à votre code.
Je pense que ce qui se passe est la suivante:
Dans une console, vous utilisez un hachage simple appelé attributes
. En tant que hash, le paramètre attributes
de 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
. En tant qu'instance de cette classe, elle ne possède pas de méthode d'instance appelée values
, mais elle possède une méthode d'instance appeléeto_h
& to_unsafe_h
, qui permettrait d'atteindre vos objectifs. Après avoir appelé to_h
dans vos paramètres, vous pouvez appeler la méthode values
.
Mot à la sagesse: si vous utilisez link_to_sorted
à partir de la gemme sortis , cela coupe les vues dans Rails 5.