Wie kann ich eine Getter-Methode in einem ActiveRecord-Modell überschreiben?


98

Ich versuche, eine Getter-Methode für ein ActiveRecord-Modell zu überschreiben. Ich habe ein Attribut nameim Modell Categoryund möchte in der Lage sein, so etwas zu tun:

def name
  name_trans || name
end

Wenn das name_transAttribut nicht Null ist, geben Sie es zurück, andernfalls geben Sie das nameAttribut zurück. Wie würde ich das machen?

Dies sollte dann normalerweise so genannt werden:

@category.name

Antworten:



98

Update: Die bevorzugte Methode gemäß dem Rails Style Guide ist die Verwendung self[:name]anstelle von read_attributeund write_attribute. Ich würde Sie ermutigen, meine Antwort zu überspringen und stattdessen diese zu bevorzugen .


Sie können dies genau so tun, außer dass Sie read_attributeden Wert des Attributs name tatsächlich abrufen und den rekursiven Aufruf der nameMethode vermeiden müssen :

def name 
  name_trans || read_attribute(:name)
end

2
Jede Idee , warum Rubocop bevorzugt self[:name]über read_attribute[:name]?
Zack Xu

18

Ich möchte eine weitere Option zum Überschreiben der Getter-Methode hinzufügen, die einfach: super ist.

def name
  name_trans || super
end

Dies funktioniert nicht nur bei Attribut-Getter-Methoden, sondern auch bei Assoziations-Getter-Methoden (auch)


1
Dies ist, was die Rails-Guides derzeit für Getter UND Setter empfehlen: api.rubyonrails.org/classes/ActiveRecord/…
sandre89

5

Das Überschreiben und Verwenden von Getter read_attributefunktioniert nicht für Assoziationen, aber Sie können es alias_method_chainstattdessen verwenden.

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override

Können Sie ein richtiges Beispiel geben ...?
Arup Rakshit

Gut. Ich habe gerade das Dokument gesehen . Wenn ich nun namedas Modellobjekt aufrufe, welches wird aufgerufen - name_with_overrideoder name_without_override?
Arup Rakshit

1
namewerde jetzt anrufen name_with_override. Wenn Sie aus irgendeinem Grund die ursprüngliche Methode aufrufen möchten, können Sie sie aufrufen name_without_override.
Patrick Oscity

OI see .. Danke für deine Antworten //
Arup Rakshit

2

Wenn Sie solche Speicherattribute verwenden

store :settings, accessors: [:volume_adjustment] 

oder mit Edelsteinen wie hstore_accessor Edelstein Link

Sie haben also die storeMethode für das Modell verwendet. Um die Methode zu überschreiben, die Sie nicht verwenden können self.read_attribute, müssen Sie stattdessen superFolgendes verwenden:

def partner_percentage
  super.to_i || 10
end

0

Wenn jemand den Wert nach der name_transGetter-Methode aktualisieren möchte , können Sie self [: name] = verwenden.

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

0

Sie können die Rails-Methode read_attribute verwenden. Rails docs


Während dieser Link möglicherweise die Frage beantwortet, sind Antworten auf nur Links auf SO nicht zulässig. Fügen Sie Ihrer Antwort einen Kontext hinzu, der sich hinter dem Link befindet. Vielen Dank! :)
AJT82
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.