2016-05-18 11 views
0

Ich erstellte ein übergeordnetes Modell mit verschachtelten Datensätzen über has_many Zuordnung und dürfen verschachtelte Datensätze über accepts_nested_attributes_for aktualisieren. Meine verschachtelten Datensätze haben das Attribut order, das im Geltungsbereich von parent_id eindeutig sein sollte. Ich weiß, dass ich Rails-Eindeutigkeitsprüfung mit :scope verwenden kann, aber ich bin entschlossen, eindeutigen mehrspaltigen Index zu verwenden.Nicht möglich, übergeordnete und verschachtelte Datensätze in Rails wegen eindeutiger Index für mehrere Spalten zu aktualisieren

So lassen Sie uns sagen, dass ich Eltern Modell Race haben:

class Race < ActiveRecord::Base 
    has_many :drivers 
    accept_nested_attributes_for :drivers, allow_destroy: true 
end 

und verschachtelt Drivers:

class Driver < ActiveRecord::Base 
    belongs_to :race 
    validates :order, numericality: { only_integer: true, 
            greater_than_or_equal_to: 0 } 
end 

Ich habe meine eindeutigen Index erstellt auch:

class AddUniqueIndexOnDriversOrder < ActiveRecord::Migration 
    def change 
    add_index :drivers, [:order, :race_id], unique: true 
    end 
end 

Leider kann ich mit dieser Einstellung die Reihenfolge nicht ändern erstellt Drivers in Race. Wenn ich Race mit Drivers und neue vollkommen gültige Reihenfolge für jeden Driver Datensatz aktualisieren möchte, führt Rails dieses Update nicht als eine Transaktion aus, und mein Index unterbricht den gesamten Vorgang. Gibt es einen Hinweis, wie Sie DB-Constraints beibehalten und das übergeordnete Objekt mit verschachtelten Datensätzen in einem Vorgang aktualisieren können?

+0

Welchen Code verwenden Sie, um die Aktualisierungen vorzunehmen? Das kann möglicherweise geändert werden, damit es funktioniert. –

+0

@MichaelGaskill Ich habe versucht, Standard-Rails-Methode zu verwenden: 'Race.update (race_params)' – przemod

+0

Ich meinte, welche Logik verwenden Sie? Bitte zeigen Sie den Code-Block an, der den 'update'-Anruf auslöst. Der ganze Block, der sich damit beschäftigt, die Reihenfolge der Fahrer den Rennen zuzuweisen. Das ist der Schlüssel. –

Antwort

0

Nach mehreren Stunden des Suchens und Grabens fand ich endlich die Antwort auf meine Frage! Die Lösung verwendet DEFERRABLE CONSTRAINTS in der Datenbank, etwas, das mir vorher nicht bekannt war.

Diese Art von Einschränkungen müssen nicht sofort ausgeführt werden, sie können ihre Prüfungen am Ende der Transaktion durchführen. Dieser genaue Fall ist in https://hashrocket.com/blog/posts/deferring-database-constraints perfekt beschrieben.

Verwandte Themen