2009-06-26 31 views
1

Ist es in ActiveRecord möglich, den Namen eines Attributs so anzupassen/zu überschreiben, dass es nicht mit dem Spaltennamen in der Datenbank übereinstimmt?Benutzerdefinierte benannte Attribute in Rails

Mein spezieller Fall beinhaltet eine ältere Spalte, "Revision", die ich zu diesem Zeitpunkt nicht entfernen kann. Der Spaltenname steht in Konflikt mit acts_as_audited. Was natürlich den alten Code, den ich brauche, bis meine Migrationen abgeschlossen sind.

Meine gewünschte Lösung wäre, den Attributnamen für diese Spalte zu überschreiben und die wenigen Bereiche, die sie aufrufen, zu aktualisieren. Dadurch kann die Legacy-Spalte neben acts_as_audited laufen.

Antwort

3

Ich habe acts_as_audited nicht verwendet, aber ich nehme an, seine Implementierung überschreibt den Accessor für diese Spalte. In diesem Fall sollten Sie in der Lage sein, so etwas zu tun, nur:

class ActiveRecord::Base 
    def self.name_column(column_name, new_name) 
    define_method(new_name) {read_attribute column_name} 
    define_method("#{new_name}=") {|value| write_attribute column_name, value} 
    define_method("#{new_name}?") {attribute_present? column_name} 
    end 
end 

Diese werden ohne Umweg über den außer Kraft gesetzten Accessor direkt die in column_name benannten Spalt zugreifen.

Oh, Bonus Vervielfältigung zerstörende metaprogramming Antwort:

class ActiveRecord::Base 
    def self.name_column(column_name, new_name) 
    { '' => :read_attribute, 
     '=' => :write_attribute, 
     '?' => :attribute_present? }.each do |suffix,method| 
     define_method("#{new_name}#{suffix}") {|*args| send method, column_name, *args} 
    end 
    end 
end 

Nur weil ich zu zeigen, wie es getan werden kann.

+0

Ich gebe das eine Chance und lass es dich wissen. Schöne Meta. – catalpa

+0

Das gibt mir einen Fehler: NoMethodError: undefinierte Methode 'define_method' – catalpa

+0

define_method ist privat, Sie müssen also im Kontext der Klasse sein, zu der Sie die Methode hinzufügen. (Ich es auseinander brach auf einige der Bereiche, machen ein bisschen mehr wiederverwendbar) def after_initialize \t name_column 'Revision', 'legacy_revision' Ende def name_column (column_name, new_name) { '' =>: read_attribute, '=' =>: write_attribute, '?' =>: attribut_präsent? } .each do | suffix, Methode | add_method (Dokument, "# {neuer_name} # {suffix}") {| * args | senden Methode, column_name, * args} Ende Ende def add_method (c, m, & b) \t c.class_eval {define_method (m, & b)} Ende – catalpa

0

Erstellen Sie eine Migration, um die Spalte von der Revision in was auch immer-Sie-wollen umzubenennen. Dann können Sie eine attr_accessor: revision deklarieren und verwenden, ohne das Attribut einem Datenbankfeld zuordnen zu müssen.

+0

attr_accessor würde nicht mit acts_as_auditiert arbeiten, b/c es hat eine Attribut-Revision für jedes Modell, das auditiert wird. Diese Überschreibung verursacht mein Problem. Das Attribut selbst benötigt einen neuen Namen, aber ich versuche, dies ohne Änderungen an der Datenbank zu erreichen. Ich verlasse das als letzten Ausweg. – catalpa

Verwandte Themen