2016-07-29 36 views
1

Ich habe ein Modell Family genannt, und es hat eine has_many Beziehung zu Parent:Wie kann ich die abhängig ändern: zerstören Abfrage für has_many Beziehung

class Family < ActiveRecord::Base 
    has_many :parents, :dependent => :destroy 
end 

Wenn ein Benutzer eine Family löscht, sollte es löschen Sie alle zugehörigen Parent.

Es gibt einen großen Haken: Ich habe eine Multi-Tenant-Umgebung (mit dem Apartment Juwel) und Eltern sind im öffentlichen Schema. Daher muss ich nur die Eltern auswählen in dem gleichen Konto sollte gelöscht werden.

Gerade jetzt, destroy, wenn auf dem Family genannt wird, erhalte ich:

SELECT "public"."users".* FROM "public"."users" WHERE "public"."users"."type" IN ('Parent') AND "public"."users"."family_id" = $FAMILY_ID

Ich muss es sein:

SELECT "public"."users".* FROM "public"."users" WHERE "public"."users"."type" IN ('Parent') AND "public"."users"."family_id" = $FAMILY_ID AND "public"."users"."account_id" = $CURRENT_ACCOUNT_ID

Gibt es eine Möglichkeit, die Family.destroy Methode außer Kraft setzen so dass es nur die richtigen verbundenen Datensätze auswählt?

+0

Sie hier einen Bereich hinzufügen können 'has_many zu filtern: Eltern, ->() {}: abhängig =>: destroy'. Auf diese Weise können Sie die Datensätze bedingt löschen. Übergeben Sie die 'CURRENT_ACCOUNT_ID' als Argument für den Bereich Lambda. –

+0

@ArupRakshit Ist das möglich, wenn 'CURRENT_ACCOUNT_ID' nur im Controller verfügbar ist, da es Teil der Anfrage ist? –

+1

Ich habe dich nicht verstanden. :) Aber Sie können den Wert wie 'Family.parents (CURRENT_ACCOUNT_ID) .destroy_all' von jedem wo übergeben. –

Antwort

0

Hier ist die Lösung, mit der ich ging. Ich habe die dependent: :destroy-Klausel aus der has_many :parents-Beziehung im family.rb-Modell entfernt. Stattdessen führe ich die Kaskadierung in der destroy Aktion Familie Controllers löschen:

def destroy 
    @family = Family.find(params[:id]) 
    authorize @family 

    parents = @family.parents.for_account(current_account.id) 

    @family.destroy 

    if @family.destroyed? 
    parents.destroy_all 
    end 

    redirect_to families_path 
end 

Ich hatte dies in der Steuerung zu tun, weil die Steuerung des current_account bewusst ist, während das Modell nicht ist. Die for_account Methode auf dem Eltern-Modell wie folgt aussieht:

scope :for_account, -> (id) { where(:account_id => id) }