Callback oder nicht

Hallo Gruppe,

ich suche gerade nach der besten Methode, um CRUD Actions in einem Model
zu überschreiben. Ziel: Beim Speichern sollen Daten manipuliert werden,
beim Lesen sollen diese Manipulationen wieder rückgängig gemacht werden
(…nein, es geht nicht um Verschlüsselung)

Einen eigenen Generator will ich dafür nicht bauen, also bleibt nur, die
entsprechenden Methoden im Model - erbend von ActiveRecord::Base zu
überschreiben.

Hier kommen - soweit ich das sehe - save und save! für Create und Update
ins Spiel, find und find_by_sql(deprecated?) für Read.

Ist meine Denke falsch, wenn ich ein Model definiere, save und find
überschreibe, oder gibt es eine bessere Möglichkeit?

Callbacks scheiden in meinem Falle aus, da ich keinen Callback
‘after_read’ oder ‘after_find’ finde, ich ausserdem hinterher aus dem
Model auch ein Plugin acts_as_foobar abstrahieren möchte, von dessen
Klassen neue Klassen wiederum erben (und somit auch meine angepasste
save und find).

Wenn das die Strategie sein sollte, bleibt eine weitere Frage. Die zu
überschreibende save Methode muss sich je nach Fall (Create / Update)
etwas anders verhalten. Kann save über reflection herausfinden, von wem
es aufgerufen wurde?

Für Hinweise auch gern in anderer Richtung bin ich dankbar.

Grüße
Jan Rösner

[email protected]

Hallo,

On Nov 6, 2007 3:20 PM, Jan R. [email protected] wrote:

ich suche gerade nach der besten Methode, um CRUD Actions in einem Model
zu überschreiben. Ziel: Beim Speichern sollen Daten manipuliert werden,
beim Lesen sollen diese Manipulationen wieder rückgängig gemacht werden
(…nein, es geht nicht um Verschlüsselung)

Callbacks scheiden in meinem Falle aus, da ich keinen Callback
‘after_read’ oder ‘after_find’ finde, ich ausserdem hinterher aus dem
Model auch ein Plugin acts_as_foobar abstrahieren möchte, von dessen
Klassen neue Klassen wiederum erben (und somit auch meine angepasste
save und find).

Wieso nicht zumindest für das speichern und updaten einfach
“before_save” und “before_update” verwenden? Für das “read” schreibst
Du einfach eine Methode im Model, die Dir das Attribut zu dem machst,
was Du brauchst. Du sagst zwar, dass das nichts mit Verschlüsseln zu
tun hat, aber die Vorgehensweise ist doch identisch, oder nicht?

Andreas

Ebenfalls hallo,

Am Tue, 6 Nov 2007 16:31:38 +0100 schrieb “Andreas R.”
[email protected]:

Wieso nicht zumindest für das speichern und updaten einfach
“before_save” und “before_update” verwenden?

Bzw. before_create und before_update erbsenzähl :slight_smile:

Für das “read” schreibst Du einfach eine Methode im Model, die Dir das Attribut zu dem machst,
was Du brauchst.

Wie wär’s in dem Fall mit dem hübschen aber leider wenig bekannten
#attribute_method_suffix? Du könntest dann weiterhin ungestört auf die rohen
Werte zugreifen (sofern man das will) und mit einem Suffix auf die
“übersetzten” Werte.

Beste
GrüßeMoritz

Hi Moritz,

Wie wär’s in dem Fall mit dem hübschen aber leider wenig bekannten
#attribute_method_suffix? Du könntest dann weiterhin ungestört auf
die rohen Werte zugreifen (sofern man das will) und mit einem Suffix
auf die “übersetzten” Werte.

Das hört sich gut an. Werd ich mal ein wenig mit rumspielen. Danke.

Grüße
Jan R.
[email protected]

Hi Andreas,

Wieso nicht zumindest für das speichern und updaten einfach
“before_save” und “before_update” verwenden?

Hört sich gut an.

Für das “read” schreibst
Du einfach eine Methode im Model, die Dir das Attribut zu dem machst,
was Du brauchst. Du sagst zwar, dass das nichts mit Verschlüsseln zu
tun hat, aber die Vorgehensweise ist doch identisch, oder nicht?

Prinzipiell ja, das Problem: In Zukünfigen Klassen, welche eben genau
von dieser via acts_as erben, kann es ja eben Attribute geben, die ich
jetzt noch nicht kenne. Allerdings wird es einen Hash in der Klasse
geben, welcher Symbole aller betreffenden Atribute enthält, die eben
“bearbeitet” werden sollen.

Grüße
Jan R.
[email protected]

Jan R. wrote:

Callbacks scheiden in meinem Falle aus, da ich keinen Callback
‘after_read’ oder ‘after_find’ finde, ich ausserdem hinterher aus dem
Model auch ein Plugin acts_as_foobar abstrahieren möchte, von dessen
Klassen neue Klassen wiederum erben (und somit auch meine angepasste
save und find).
Hallo Jan,

wie schon korrekt gesagt wurde, gibt es after_update und after_create.
Es gibt auch ein after_find und after_initialize. Dubioserweise wird
after_initialize auch nach find Aufrufen getriggert, aber after_find
sollte dir weiterhelfen. Aus Performance Gründen muss man after_find
direkt auf den model klassen definieren, im gegensatz zu den anderen
callbacks. das bedeutet einfach, dass du

def after_find

code

end

in deinem AR Model definieren musst.

Falls Du Attribut-weise arbeiten willst: da hatte ich es immer so
gemacht dass ich read_attribute bzw write_attribute genutzt habe. etwa
so:

class Test < AR::Base

def read_attribute_with_cool_feature(attr_name)
do.cool.stuff(attr_name)
read_attribute_without_cool_feature(attr_name)
end

alias_method_chain :read_attribute, :cool_feature

end

Funktioniert auch wunderbar wenn man code im plugin style schreiben
möchte.

Callbacks sind auf jeden fall ein besserer Ansatz als save/create/find
zu überschreiben.

Du solltest auch anstatt mit Vererbung dann eher mit Modules oder gar
Macro Methoden arbeiten, wenn Du das zu einem Plugin machen willst. Dazu
siehst Du in den meisten guten Plugins guten Code den man sich abgucken
kann, zB bei acts_as_versioned.

Gruß
Thomas