2016-12-01 4 views
1

Dies ist der aktuelle Code, den ich habe:Einmaligkeit Validierung auf verschachtelte Attribute

class Parent < ActiveRecord::Base 
    has_many :children 
end 

class Child < ActiveRecord::Base 
    belongs_to :parent 

    validates :name, :presence => true, :uniqueness => { :scope => :parent_id, :case_sensitive => false } 
end 

Mein Problem ist, dass, wenn ich tun:

Parent.create(params) 

Die Einzigartigkeit Validierung prüft nur, bevor ein Kind erstellt wird. Es wird nie mehr überprüft, nachdem jedes Kind hinzugefügt wurde. Gibt es eine Möglichkeit, Validierungen zwischen jedem hinzuzufügenden Kind aufzurufen?

Wenn es keine ActiveRecord Möglichkeit gibt, dies zu tun, werde ich meine eigene Validierungsmethode für Eltern schreiben. Aber ich frage mich, ob es einen "leichteren" Weg gibt.

Dies ist die Protokolle:

Child Exists (0.4ms) 
Child Exists (0.2ms) 
Parent Exists (0.3ms) 
SQL (0.6ms) INSERT INTO "parents" 
SQL (0.3ms) INSERT INTO "children" 
SQL (0.3ms) INSERT INTO "children" 
+0

Eigentlich führt es Validierung vor der Erstellung von jeder 'Child'-Instanz. Angenommen, Sie haben bereits Child mit dem Namen "foo" in der Datenbank gespeichert, haben Sie keine Möglichkeit, einen anderen Datensatz mit demselben Namen zu speichern (im Bereich "parent_id"). Und es ist eine gute Übung, Uniq-Index auf DB-Ebene hinzuzufügen. –

+0

Ich habe das tatsächlich versucht und ich habe das OP aktualisiert, um die Protokolle anzuzeigen. Ich habe alle zusätzlichen Sachen entfernt, aber Sie können sehen, dass die Validierung alle gleichzeitig prüft, bevor ein Kind hinzugefügt wird. Wenn Sie also zwei Kinder gleichzeitig erstellen, werden Validierungen durchgeführt. Und ja, ich kann einen Uniq-Index auf der DB-Ebene hinzufügen, aber ich möchte eine konsistente Fehlermeldung. – Dragonfly

Antwort

1

Sie diese jsut versuchen. etwas aussehen wie

# app/validators/products_name_uniqueness_validator.rb 
class ProductsNameUniquenessValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    record.errors[attribute] << "Products names must be unique" unless value.map(&:name).uniq.size == value.size 
    end 
end 

# app/models/shop.rb 
class Shop < ActiveRecord::Base 
    validates :products, :products_name_uniqueness => true 
end 
+0

Gibt es eine Möglichkeit, dies zu tun, ohne eine andere Datei zu erstellen? Kann ich diese Methode zur Shop-Klasse hinzufügen? –

Verwandte Themen