Ruby on Rails ActiveCord Model Accessors verstehen
-
22-09-2019 - |
Frage
Mein Modell "DataFile" hat eine Reihe von Feldern, die ich gerne von außerhalb des Modells festlegen möchte, z. B.
file = DataFile.new file.owner = 123
Soweit ich weiß, müsste ich für jedes Feld einen "Attr_Accessor: Field" in mein Modell platzieren, das ich gerne von außen ändern möchte. Der obige Code läuft jedoch gut, ohne dass Attr_Accessors definiert ist und das Feld des Eigentümers auf 123 festgelegt hat. Warum ist das so?
Ich hatte erwartet, dass ich einen "nicht definierten" Fehler oder so ähnliches erhalten würde.
Lösung
Da Rails 'ORM das ActiveCord -Muster verwendet, werden zwei Methoden für jede Spalte in der Datenbank automatisch erstellt, die dieser Tabelle zugeordnet ist: Spaltenname, und columnName =. Dies geschieht "automatisch" als Ergebnis Ihres Modells, das von ActivereCord :: Base erbt. Diese Methoden werden unter Verwendung von Rubys Metaprogrammierungsanlagen definiert und zum Zeitpunkt der Erstellung der Klassen dynamisch erstellt.
Für weitere Informationen darüber, was genau los ist, würde ich einen Blick auf die Quelle der Rails werfen. Das Obige reicht jedoch wahrscheinlich aus, um Ihnen ein Arbeitsverständnis dafür zu vermitteln, was passiert.
Andere Tipps
Drew und Zepplock haben es richtig gemacht, aber ich werde einfach noch etwas hinzufügen. Die Accessors, die Rails (eigentlich ActiveCord) für Datenbankfelder erstellt hat, sind keine Ruby -Accessors. Wenn Sie Skript/Konsole verwenden, werden Sie feststellen, dass der Eigentümer keine Instanzvariable der Objektdatei ist.
Es ist wahrscheinlich, dass Sie dies nicht bemerken würden, bis Sie sich von den Standard -Zubehör wegwagen und versuchen, @owner innerhalb einer in der Datei in der Datei zu befriedigen Methode zu manipulieren. Wenn Sie Ruby gleichzeitig lernen, lernen Sie Schienen (was ich getan habe), dann werden Sie dies wahrscheinlich irgendwann darauf treffen. Dies ist der Grund, warum Sie schreiben müssen:
class MyClass < ActiveRecord::Base
def invalidate_owner
self.owner = owner << " no longer owns this"
save
end
end
Anstatt von
class MyClass < ActiveRecord::Base
def invalidate_owner
self.owner << " no longer owns this"
save
end
end
Höchstwahrscheinlich ist "Eigentümer" Teil Ihres Datenbankmodells. Die Accessors für die Datenbankfelder sind für Sie automatisch generiert.