简体   繁体   English

Ruby / Rails继承,覆盖子类中超类中定义的验证器

[英]Ruby/Rails inheritance, overriding validators defined in super-class in sub-class

I have the following rails/paperclip validator: 我有以下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

the validator is used in both super (super-class is not abstract so can be instanciated) and sub-class. 验证器用于super(超类不抽象,因此可以实例化)和子类。 In the sub-class I need to change the ratios allowed: 在子类中,我需要更改允许的比率:

Super-class: 超类:

class Superclass
    validates_attachment :logo, :image_ratio => { :ratio  => {"1:1" => "28", "4:1" => "50", "5:1" => "40"} }
end

Sub-class: 子类:

class Subclass < Superclass
  validates_attachment :logo, :image_ratio => { :ratio  => {"1:1" => "40", "2:1" => "60"} }
end

The validator works as expected in the super-class however seems to ignore the new ratios given in the sub-class. 验证器在超类中按预期工作,但似乎忽略了子类中给出的新比率。
Am I trying to use the validators in a non Rails way? 我是否尝试以非Rails方式使用验证器? How should I be using the validators in a situation like the one described above? 在如上所述的情况下,我应该如何使用验证器?

When you inherit from the superclass you also get the validators from it. 从超类继承时,您也可以从中获取验证器。 I'm not 100% sure of this but I think that you just add your new validators to the list of old ones, ie both constrains apply. 我不是100%肯定这一点,但我认为你只是将新的验证器添加到旧的验证器列表中,即两个约束都适用。

I think the easiest solution is to put common logic in a module or inherit from a common superclass. 我认为最简单的解决方案是将通用逻辑放在模块中或从公共超类继承。 You could also do something like this, but I think it's pretty ugly: 你也可以这样做,但我认为这很难看:

class Superclass
    with_options :unless => Proc.new { |a| a.validators.any? } do |super_validators|
        super_validators.validates :password, :length => { :minimum => 10 }
    end
end

This isn't ideal as a solution, but fairly clean. 这不是理想的解决方案,但相当干净。

Just use custom validation based on the type. 只需根据类型使用自定义验证。 This way you will have both validators defined in the super class, but it will definitely work. 这样你就可以在超类中定义两个验证器,但它肯定会起作用。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM