2017-12-05 3 views
0

Nach dem Durchkämmen der Dokumentation habe ich eine schwierige Zeit zu verstehen, was Callback ich verwenden sollte.Rails ActiveRecord Callbacks: Update, wenn vorhanden, Create, wenn nicht existiert

Pseudocode:

wenn child_id und outage_id existieren nicht

eine Beziehung (INSERT-Anweisung) erstellen

wenn outage_id geändert wird

ändern Beziehung (UPDATE-Anweisung)

Diese Einsätze und Updates werden über collection_check_boxes behandelt

Es gibt drei Modelle. Beziehung, Ausfall und Kind.

class Outage < ApplicationRecord 
    has_many :relationships 
    has_many :children, through: :relationships 
end 

class Child < ApplicationRecord 
end 


class Relationship < ApplicationRecord 
    belongs_to :outage 
    belongs_to :child 

    validate :check_if_exists, if: :outage_id_changed? 

    private 

    def check_if_exists 
    Relationship.where(child_id: self.child_id).update_all(outage_id: self.outage_id) 
    end 
end 

Das Problem, das ich jetzt mit Blick auf bin ist, dass ein UPDATE immer direkt vor dem INSERT auftritt, egal was passiert. Eine UPDATE sollte nur auftreten, wenn der Datensatz existiert und outage_id geändert wird.

Jeder Einblick, was ich hier falsch mache, würde geschätzt werden.

+0

statt einer Überprüfung Schauen Sie sich den 'after_save'-Hook an, dort können Sie 'saved_changes' auf den Datensatz zugreifen und Ihre Logik darauf aufbauen Vergleichen mit den neuen Attributen – neongrau

+0

Danke @neongrau, werde ich das untersuchen. – DnfD

Antwort

0

du versuchen können,

class Relationship < ApplicationRecord 
    before_update :check_if_exists, if: :outage_id_changed? 

    private 
    def check_if_exists 
     # Your logic 
    end 
end 

Hinweis: In Ihrem Code check_if_exists wird auch auf erstellen laufen, da outage_id wird nil-<some_id> Wechsel während erstellen

jedoch before_update verwenden wird sicherstellen, dass es nur auf dem Update

ausgeführt wird Beachten Sie auch, dass Sie update_all verwenden, was zu Ergebnissen führt eine direkte Datenbankabfrage und ist nicht in Transaktion eingeschlossen. Das heißt, wenn alle Updates fehlschlagen, werden die über update_all vorgenommenen Änderungen nicht rückgängig gemacht

+0

Guter Punkt auf "Null". Die "UPDATE" -Aktion wird jedoch nicht erkannt: Es ist immer eine Einfügung, es sei denn, ich erzwinge das Problem mit 'update_all'. Jedesmal, wenn ich »collection_check_boxes« verwende, sieht es es immer als »INSERT« an. Repo: https://github.com/ornerymoose/TestAppForStackOverflow – DnfD

Verwandte Themen