8
votes

Pourquoi les attributs de modèle des rails ne sont-ils pas accessibles à l'aide de symboles au lieu de chaînes?

J'ai besoin de comparer des rails (2.3.11) des valeurs d'attribut de modèle avant et après une mise à jour de la base de données, donc je commence à trouver mon enregistrement et en enregistrant les valeurs d'attribut existantes dans un hachage, comme suit:

model_val = work_effort.attributes[key.to_s]


0 commentaires

4 Réponses :


13
votes

Le hachage est retourné lorsque vous appelez #attributes sur une instance AR comporte des touches de chaîne, c'est pourquoi un symbole comme index dans le hachage ne fonctionne pas dans votre cas. Il y a une sous-classe de hachage appelé hashwithindiferenaccess qui convertit automatiquement les index de symboles en chaînes.

Très souvent dans des rails, vous rencontrerez hashwithindiferencess instances. Un exemple parfait est la variable des params que vous accédez dans votre contrôleur et votre code de vue.

Essayez d'utiliser work_effort.attributes.with_indifferent_access [clé]

Vraiment, c'est juste faire la même chose que vous êtes, mais cela le fait dans les coulisses.


2 commentaires

Cela fonctionne mais y a-t-il une raison pour laquelle je ne devrais pas utiliser la clé.To_s ou est l'argument convaincant que la plupart de tout le monde utilise avec_indifferent_access?


Je voudrais simplement utiliser la clé.To_s à moins d'avoir une raison très convaincante non aussi. Dans votre cas, il apparaît que la clé.Te_s est réellement moins chère qu'avec_indifferent_access



1
votes

Vous voudrez peut-être utiliser: stringify_keys! qui est largement utilisé tout le code des rails.

def rollup_ancestor_updates(work_effort, ancestor_rollup_fields)
  ancestor_rollup_fields.stringify_keys!.each do |key, value|
    model_val = work_effort.attributes[key]
  end
  #....
end


2 commentaires

Comment cela peut-il être supprimé dans mon exemple de code pour le faire fonctionner sans utiliser Key.To_s? Merci; En attendant, je vérifie dans l'autre exemple (avec_indifferent_access que je me souviens maintenant de voir dans d'autres endroits).


Je pense que vous devriez avoir dit symbolise_keys! . Cette idée vaut mieux que d'appeler avec_indifferent_access car il ne crée pas de nouveau hachage. À moins que, bien sûr, vous devez utiliser des clés de chaîne et de symboles.



8
votes

Vous pouvez écraser la méthode des attributs avec votre propre.

Ouvrez votre classe WordFffort xxx

puis lorsque vous appelez work_effort.attributes, vous aurez des clés symbolisées dans le hachage.


0 commentaires

1
votes

Tous les modèles de vos rails peuvent avoir des noms d'attributs symbolisés: xxx

alors vous pouvez appeler mymodel.attribute_names (symboles = true) et récupérer [: ID ,: my_attribute ,: updated_at, ...] tout en permettant toujours attribute_names pour renvoyer des chaînes.

Notez que Vous avez besoin des parenthèses après Super Pour éviter une erreur d'argument avec la fonction définie à l'origine.


0 commentaires