2012-10-24 90 views
8

我有一個非常通用的驗證器,我想傳遞它的參數。Rails/ActiveModel傳遞參數到EachValidator

下面是一個例子模型:

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 

和實施例驗證:

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 

是否有任何方式將參數傳遞給校驗器取決於它正在驗證哪個字段?

感謝

+0

什麼是你想通過這樣做是爲了達到什麼目的?這並不是我給出Rails API的最佳方式。 – dpassage

+0

在我的原始代碼中,我想查找模型中是否存在循環依賴項。 ModelA有許多模型B.模型B有一個模型A.我想驗證模型A沒有循環返回到它自己。事情是,我有兩個需要驗證週期的不同關係,它們之間的驗證器之間存在非常小的差異。我想知道是否可以通過傳遞哪些字段來搜索循環,而不是重寫相同的循環邏輯和驗證器。 – GTDev

+0

我認爲你可能會更好使用子類化,而不是參數化。 – dpassage

回答

13

我沒有意識到這一點下去,但如果你想傳遞一個參數,然後通過一個哈希generic:而不是trueThis post細節你想跟隨確切的過程:

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現在應該有機會獲得這兩個參數你想在驗證通過:options[:order_type]options[:task_type]

它可能會更有意義,然而,這些成兩個驗證,既繼承了共享行爲的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