Comment puis-je écraser une méthode getter dans un modèle ActiveRecord?

J’essaie d’écraser une méthode getter pour un modèle ActiveRecord. J’ai un atsortingbut appelé name dans la Category du modèle, et j’aimerais pouvoir faire quelque chose comme ceci:

 def name name_trans || name end 

Si l’atsortingbut name_trans n’est pas nul, renvoyez-le, sinon, retournez l’atsortingbut name . Comment pourrais-je faire ça?

Cela devrait alors s’appeler normalement comme ceci:

 @category.name 

    Le Guide de style Rails recommande d’utiliser self[:attr] sur read_atsortingbute(:attr) .

    Vous pouvez l’utiliser comme ceci:

     def name name_trans || self[:name] end 

    Mise à jour: La méthode préférée selon le guide de style Rails consiste à utiliser self[:name] au lieu de read_atsortingbute et write_atsortingbute . Je vous encourage à sauter ma réponse et préférer celle-ci .


    Vous pouvez le faire exactement comme cela, sauf que vous devez utiliser read_atsortingbute pour récupérer la valeur de l’atsortingbut name et éviter l’appel récursif à la méthode name :

     def name name_trans || read_atsortingbute(:name) end 

    Je voudrais append une autre option pour écraser la méthode getter, qui est simplement: super.

     def name name_trans || super end 

    Cela fonctionne non seulement sur la méthode getter des atsortingbuts, mais aussi sur les méthodes getter des associations , aussi

    Le remplacement de getter et l’utilisation de read_atsortingbute ne fonctionnent pas pour les associations, mais vous pouvez utiliser alias_method_chain place.

     def name_with_override name_trans || name_without_override end alias_method_chain :name, :override 

    Si vous utilisez des atsortingbuts de magasin comme celui-ci

     store :settings, accessors: [:volume_adjustment] 

    ou en utilisant des gemmes comme hstore_accessor gem link

    Donc, vous avez fini par utiliser la méthode store sur le modèle, puis pour remplacer ces méthodes, vous ne pouvez pas utiliser self.read_atsortingbute , vous devez plutôt utiliser super comme ça:

     def partner_percentage super.to_i || 10 end 

    Si quelqu’un veut mettre à jour la valeur après name_trans dans la méthode getter, vous pouvez utiliser self [: name] =.

     def name self[:name] = name_trans || self[:name] # don't do this, it will cause endless loop # update(name: name_trans) end 

    Vous pouvez utiliser la méthode read_atsortingbute de Rails. Rails docs