web-dev-qa-db-fra.com

Comment remplacer une méthode de lecture dans un modèle ActiveRecord?

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
88
oyvindhauge

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
102
Wonsup Lee

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
97
meagar

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)

14
lei liu

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
5
Patrick Oscity

Si vous utilisez des attributs de magasin comme celui-ci

store :settings, accessors: [:volume_adjustment] 

ou en utilisant des gemmes comme hstore_accessorlien 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
2
onemanstartup

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
0
fangxing

Vous pouvez utiliser Rails read_attribute. documentation Rails

0
Rajat Bansal