2017-11-16 2 views
0

Ich benutze after_find in meinem Modell, wollte aber in einigen Fällen deaktivieren. Und ich benutze .where immer noch After_find läuft aber im Dokument sagt, dass es nur für folgende Methoden funktioniert. Wieso ist es so?Gibt es irgendeine Methode, um After_find nur in einigen Fällen zu deaktivieren

all 
first 
find 
find_by 
find_by_* 
find_by_*! 
find_by_sql 
last 

meine api (Trauben Rahmen) ist

delete '/delete_user' do 
    user_id = params[:user_id] #authenticate_current_user! 
    @user_profile = ::UserProfile.where(user_id: user_id). 
    @user_profile.destroy_all 
end 
+0

Aus welchem ​​Dokument haben Sie diese Informationen erhalten? Die [rails documentation] (http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html) sagt: * "ein' after_find'- und 'after_initialize'-Callback wird für jedes gefundene Objekt ausgelöst und von einem Finder instanziiert "*. Und die Methoden 'find_by_ *' wurden seit v4 veraltet/aus den Core-Rails entfernt und komplett in den Rails 5 entfernt. –

+0

Kannst du bitte deinen Code zeigen? Was meinst du mit "in einigen Fällen deaktivieren"? Es gibt wahrscheinlich eine sauberere Lösung für Ihr Problem, die überhaupt nicht "nachher" betrifft. –

+0

Sah in http://guides.rubyonrails.org/active_record_callbacks.html. Hat den Code auch hinzugefügt. –

Antwort

0

Der after_find Rückruf wird nicht von Ihrem where Aufruf aufgerufen wird; Es wird durch Ihren Anruf destroy_all aufgerufen. destroy_all wird jedes UserProfile-Objekt (und seine zugeordneten Objekte) instanziieren und seine destroy-Methode eins nach dem anderen aufrufen.

Wenn Sie sofort alle UserProfile Objekte löschen möchten, ohne sie zu instanziieren (und alle Rückrufe Skipping), dann kann man nennen:

UserProfile.where(user_id: user_id).delete_all 

Weitere Informationen zu den Unterschieden zwischen destroy_all and delete_all finden Sie in andere Antworten auf Stackoverflow, aber die Unterschiede über die Sie sich interessieren, sind:

  1. es wird die Aufzeichnung nicht instanziiert
  2. es wird nicht zugeordneten Objekte
  3. löschen alle Rückrufe

nicht berufen werde ich würde empfehlen, dass Sie so, wie Sie es verwenden nicht after_find verwenden. Es gibt lots of ways to skip callbacks aber almost nobody uses after_find. (im Vergleich zu after_create, zum Beispiel)

Die Optionen zum Überspringen after_find Rückrufe sind begrenzt. Dafür gibt es keine built-in Rails methods. (Außer wie oben beschrieben) Wenn Sie unbedingt den Rückruf halten müssen, dann Ihre beste Wette ist eine bedingte an die Callback-Definition hinzuzufügen:

after_find :foo, if: -> { <some logic> } 

Wenn Sie eine bedingte so verwenden, dann müssen Sie anfangen, darüber nachzudenken wie diese Variable in einer Multithread-Umgebung gelesen und gesetzt wird und wie man gleichzeitige Anfragen bearbeitet, ohne eine Race-Bedingung zu erzeugen, und einen unschönen Pfad einschlägt, der besser gehandhabt wird, indem man after_find nicht wie beschrieben verwendet.

+0

Nein. Wenn ich in meiner Konsole versucht habe, ** where ** -Klausel zu verwenden, wird after_find aufgerufen. Für ex: User.where (id: 2) ruft after_find-Methode auf. –

+0

@shahanahamza Das liegt nur daran, dass Sie es in der Konsole ausführen. Wenn Sie 'UserProfile.where' in der Konsole ausführen, wird' irb' jeden Datensatz instanziieren, damit er sie bequem für Sie anzeigen kann. Wenn "irb" den Datensatz instanziiert, wird der 'after_find'-Callback ausgelöst. Dies geschieht nur, weil die Konsole die Datensätze instanziiert, um sie anzuzeigen. – anothermh

Verwandte Themen