J'essaie d'écraser une méthode de lecture pour un modèle ActiveRecord. J'ai un attribut appelé name
dans le modèle Category
, et j'aimerais pouvoir faire quelque chose comme ceci:
def name
name_trans || name
end
Si name_trans
attribut n’est pas nil, retournez-le, sinon retournez name
attribut. Comment je ferais ça?
Ceci devrait alors s'appeler normalement comme ceci:
@category.name
Le Guide de style Rails recommande d'utiliser self[:attr]
Sur read_attribute(:attr)
.
Vous pouvez l'utiliser comme ceci:
def name
name_trans || self[:name]
end
Mise à jour: la méthode recommandée selon le Guide de style Rails consiste à utiliser self[:name]
au lieu de read_attribute
et write_attribute
. Je vous encourage à ignorer ma réponse et à préférer plutôt celui-ci .
Vous pouvez le faire exactement comme ça, sauf que vous devez utiliser read_attribute
pour récupérer la valeur de l'attribut name et éviter l'appel récursif à la méthode name
:
def name
name_trans || read_attribute(:name)
end
Je voudrais ajouter une autre option pour remplacer la méthode getter, qui est simplement: super.
def name
name_trans || super
end
cela fonctionne non seulement sur la méthode des attributs getter, mais aussi sur les méthodes des associations getter (trop)
Ignorer le getter et utiliser read_attribute
ne fonctionne pas pour les associations, mais vous pouvez utiliser alias_method_chain
au lieu.
def name_with_override
name_trans || name_without_override
end
alias_method_chain :name, :override
Si vous utilisez des attributs de magasin comme celui-ci
store :settings, accessors: [:volume_adjustment]
ou en utilisant des gemmes comme hstore_accessor
lien bijo
Donc, vous avez fini par utiliser la méthode store
sur le modèle, puis vous ne pouvez pas utiliser la méthode self.read_attribute
, vous devez utiliser à la place super
comme ceci:
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 Rails read_attribute. documentation Rails