J'utilise Ruby on Rails 3.2.2 et j'aimerais savoir si ce qui suit est un moyen "correct" / "correct" / "sûr" de remplacer une méthode setter pour un attribut my class.
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self[:attribute_name] = value
end
Le code ci-dessus semble fonctionner comme prévu. Cependant, j'aimerais savoir si, en utilisant le code ci-dessus, j'aurai des problèmes à l'avenir ou, du moins, à quels problèmes "devrais-je m'attendre" / "pourraient survenir" avec Ruby on Rails . Si ce n'est pas la bonne façon de remplacer une méthode setter, quelle est la bonne façon?
Remarque : si j'utilise le code
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self.attribute_name = value
end
J'obtiens l'erreur suivante:
SystemStackError (stack level too deep):
actionpack (3.2.2) lib/action_dispatch/middleware/reloader.rb:70
Réponses:
=================================================== ========================== Mise à jour: 19 juillet 2017
Maintenant, la documentation Rails suggère également d'utiliser
super
comme ceci:=================================================== ==========================
Réponse originale
Si vous souhaitez remplacer les méthodes de définition des colonnes d'une table lors de l'accès via des modèles, c'est la manière de le faire.
Voir Remplacer les accesseurs par défaut dans la documentation Rails.
Donc, votre première méthode est la bonne façon de remplacer les setters de colonne dans Models of Ruby on Rails. Ces accesseurs sont déjà fournis par Rails pour accéder aux colonnes de la table en tant qu'attributs du modèle. C'est ce que nous appelons le mappage ORM ActiveRecord.
Gardez également à l'esprit que la partie
attr_accessible
supérieure du modèle n'a rien à voir avec les accesseurs. Il a une fonctionnalité complètement différente (voir cette question )Mais en Ruby pur, si vous avez défini des accesseurs pour une classe et que vous souhaitez remplacer le setter, vous devez utiliser une variable d'instance comme celle-ci:
Cela sera plus facile à comprendre une fois que vous saurez ce que
attr_accessor
fait. Le codeattr_accessor :name
est équivalent à ces deux méthodes (getter et setter)De plus, votre deuxième méthode échoue car elle provoquera une boucle infinie lorsque vous appelez la même méthode
attribute_name=
dans cette méthode.la source
attr_accessible
car il n'est plus là et cela devrait fonctionnersuper
?super
pourrait ne pas fonctionner. Mais il semble que ce ne soit pas le cas. Je viens de le vérifier et cela fonctionne pour moi. Aussi, cette question pose la même chosewrite_attribute
. Les conversions seront ignorées. Sachez quewrite_attribute
les conversions de fuseau horaire avec des dates seront ignorées, ce qui sera presque toujours indésirable.Utilisez le
super
mot - clé:Inversement, pour remplacer le lecteur:
la source
Dans les rails 4
disons que vous avez un attribut d' âge dans votre tableau
Remarque: pour les nouveaux arrivants dans les rails 4, vous n'avez pas besoin de spécifier attr_accessible dans le modèle. Au lieu de cela, vous devez mettre en liste blanche vos attributs au niveau du contrôleur en utilisant la méthode d' autorisation .
la source
J'ai trouvé que (au moins pour les collections de relations ActiveRecord) le modèle suivant fonctionne:
(Cela récupère les 3 premières entrées non dupliquées du tableau passées.)
la source
Utilisation
attr_writer
pour écraser le setter attr_writer: nom_attributla source