2012-10-24 23 views
8

Mam bardzo ogólny walidator i chcę przekazać mu argumenty.Railsy/ActiveModel przekazywanie argumentów do EachValidator

Oto przykład model:

class User 
    include Mongoid::Document 

    field :order_type 
    has_many :orders, inverse_of :user 
    validates: orders, generic: true #i want to pass argument (order_type) 

    field :task_type 
    has_many :tasks, inverse_of :user 
    validates: tasks, generic: true #i want to pass argument (task_type) 
end 

i Przykład walidator:

class GenericValidator < ActiveModel::EachValidator 
    def validate_each(object, attribute, value) 
    if some_validation?(object) 
     object.errors[attribute] << (options[:message] || "is not formatted properly") 
    end 
    end 
end 

Czy istnieje jakiś sposób, aby przekazywać argumenty do walidatora zależnej od którego pole jest ona sprawdzanie?

dzięki

+0

Co chcesz osiągnąć w ten sposób? Nie wydaje mi się to najlepszym sposobem na to, biorąc pod uwagę Rails API. – dpassage

+0

W moim oryginalnym kodzie chcę sprawdzić, czy istnieje cykliczna zależność w moim modelu. Model A ma wiele Modelu B. Model B ma jeden Model A. Chcę potwierdzić, że nie ma cyklu od Modelu A do siebie. Chodzi o to, że mam dwie różne relacje, które muszą weryfikować cykle i między nimi jest bardzo minimalna różnica w walidatorze. Chciałem zobaczyć, czy mógłbym to zrobić generalnie przekazując pola, które będą wyszukiwać cykle, w przeciwieństwie do przepisywania tej samej logiki cyklu i walidatora. – GTDev

+0

Myślę, że może być lepiej wyłączyć przy użyciu podklasy dla tego zamiast parametryzacji. – dpassage

Odpowiedz

13

nie byłem tego świadomy albo, ale jeśli chcesz przekazać argument, a następnie przejść do generic: hash zamiast true. This post szczegóły dokładny proces jesteś chcąc podążać:

class User 
    include Mongoid::Document 

    field :order_type 
    has_many :orders, inverse_of :user 
    validates: orders, generic: { :order_type => order_type } 

    field :task_type 
    has_many :tasks, inverse_of :user 
    validates: tasks, generic: { :task_type => task_type } 
end 

GenericValidator powinien teraz mieć dostęp do obu argumentów jesteś chcących przejść w walidacji: options[:order_type] i options[:task_type].

Może to więcej sensu, jednak, aby podzielić je na dwie walidatorami, zarówno dziedziczenie udostępniony zachowanie jak wspomniano przez dpassage:

class User 
    include Mongoid::Document 

    field :order_type 
    has_many :orders, inverse_of :user 
    validates: orders, order: { type: order_type } 

    field :task_type 
    has_many :tasks, inverse_of :user 
    validates: tasks, task: { type: task_type } 
    end