2016-04-07 5 views
1

Wenn Sie direkt auf die Frage gehen möchten, gehen Sie einfach zum letzten Absatz.Verschachtelte Attribute Validierungen schlägt in der übergeordneten Zuordnung fehl

Ein Paket enthält viele Elemente, Element ist polymorph und eine der verknüpften Tabellen ist Access (also Access ist ein Element, das dem Pack hinzugefügt werden kann) Hier sind Sie die Modelle und Controller.

class Pack < ActiveRecord::Base 
    has_many :pack_items, dependent: :destroy 
    has_many :items_included, through: :pack_items, source: :item 
    accepts_nested_attributes_for :pack_items, allow_destroy: true 

    validate :valid_max_value, if: :infinite_item? 
end 

class Item < ActiveRecord::Base 
    has_many :pack_items, dependent: :restrict_with_error 
    has_many :packs, through: :pack_items 
end 

class Access < ActiveRecord::Base 
    has_one :item, as: :itemable, dependent: :destroy 
    has_one :entitlement, as: :entitlementable, dependent: :destroy 
    accepts_nested_attributes_for :item, allow_destroy: true 
    accepts_nested_attributes_for :entitlement, allow_destroy: true 
    validate :valid_max_value, if: :infinite? 

    private 

    def infinite? 
    entitlement.infinite 
    end 
end 

class PacksController < BaseController 
    def update 
    @pack = Pack.find(params[:id]) 
    if @pack.update(permitted_params) 
     ... 
    end 
    end 

    private 

    def permitted_params 
    params.require(:pack).permit(item_attributes: [:id, :name, :max_purchasable], 
           pack_items_attributes: [:id, :item_id, :amount, :_destroy]) 
    end 
end 

Es gibt eine importan Validierung in pack „valid_max_value. Wenn eine Packung innerhalb einer unendlichen Zugang hat, die max_value des Satzes sollte nie höher sein als 1. Es funktioniert perfekt, wenn ich ein Paket erstellen und ich hinzufügen dies einige Zugänge, aber das Problem ist:

  • ich habe eine Packung mit zwei Einzelteilen einen Access, das unendlich ist und einen gemeinsamen Zugang (nicht unendlich) So sollte die Pack max_value 1 sein, weil es einen unendlichen Zugang nach innen hat..
  • Jetzt bearbeite ich das Pack und lösche den unendlichen Access, also kann ich jetzt Wählen Sie einen höheren max_value, 5 in Beispiel, weil das Paket keinen Zugriff mit Einschränkung innerhalb hat.
  • Wenn ich auf update klicke, wird ein Rollback ausgeführt, weil die Validierung valid_max_value vor dem Löschen des infinite Access ausgeführt wird. Daher ist der Wert max_value ungültig, weil die Validierung von einem untergeordneten Feld abhängt.

Kurz gesagt, meine Frage ist: Wie kann ich die verschachtelten Elemente löschen, bevor die übergeordnete Validierung laufen?

Antwort

1

Sie müssen nicht löschen tatsächlich die Elemente vor der Validierung prüfen marked_for_destruction? stattdessen in Ihrer Validierungen, so dass Gegenstände, die

+0

Coole ignoriert werden gelöscht sind! Das ist ein großartiger Ansatz. Aber jetzt, wie kann ich es richtig benutzen? weil es eine has_many-through-association ist und es für die Zerstörung das pack_item anstelle des in der Validierung benötigten Items markiert. Ich kann es codieren, um das Element aus der Beziehung zu bekommen, aber ich würde es gerne wissen, dass es einen besseren Weg gibt. – Quin

+0

@Quin von der Spitze meines Kopfes, das ist der Weg zu gehen. – Vasfed