我有以下rails / paperclip验证器:
class ImageRatioValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
attr_name = "#{attribute}_width".to_sym
value = record.send(:read_attribute_for_validation, attribute)
valid_ratios = options[:ratio]
if !value.queued_for_write[:original].blank?
geo = Paperclip::Geometry.from_file value.queued_for_write[:original]
# first we need to validate the ratio
cur_ratio = nil
valid_ratios.each do |ratio, max_width|
parts = ratio.split ":"
next unless (geo.height * parts.first.to_f) == (geo.width * parts.last.to_f)
cur_ratio = ratio
end
# then we need to make sure the maximum width of the ratio is honoured
if cur_ratio
if not valid_ratios[cur_ratio].to_f >= geo.width
record.errors[attribute] << "The maximum width for ratio #{cur_ratio} is #{valid_ratios[cur_ratio]}. Given width was #{geo.width}!"
end
else
record.errors[attribute] << "Please make sure you upload a stall logo with a valid ratio (#{valid_ratios.keys.join(", ")})!"
end
end
end
end
验证器用于super(超类不抽象,因此可以实例化)和子类。在子类中,我需要更改允许的比率:
超类:
class Superclass
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "28", "4:1" => "50", "5:1" => "40"} }
end
子类:
class Subclass < Superclass
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "40", "2:1" => "60"} }
end
验证器在超类中按预期工作,但似乎忽略了子类中给出的新比率 我是否尝试以非Rails方式使用验证器?在如上所述的情况下,我应该如何使用验证器?
答案 0 :(得分:0)
当您从超类继承时,您也会从中获取验证器。我不是百分之百确定这一点,但我认为你只是将新的验证器添加到旧的验证器列表中,即两个约束都适用。
我认为最简单的解决方案是将常用逻辑放在模块中或从公共超类继承。你也可以这样做,但我认为这很难看:
class Superclass
with_options :unless => Proc.new { |a| a.validators.any? } do |super_validators|
super_validators.validates :password, :length => { :minimum => 10 }
end
end
答案 1 :(得分:0)
这不是一个理想的解决方案,但相当干净。
只需根据类型使用自定义验证。这样你就可以在超类中定义两个验证器,但它肯定会有效。
class Superclass
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "28", "4:1" => "50", "5:1" => "40"} }, :if => self.is_a?(SuperClass)
validates_attachment :logo, :image_ratio => { :ratio => {"1:1" => "40", "2:1" => "60"} }, :if => self.is_a?(SubClass)
end