从方法加载模型验证?

时间:2013-08-22 19:45:29

标签: ruby-on-rails ruby-on-rails-4

我希望有一个带有默认验证的超类和可以覆盖默认验证的子类。

class Foo < ActiveRecord::Base
  FIELDS = [:field1, :field2]
  after_initialize :include_rules

  def include_rules
    FIELDS.each do |field|
      self.class.send(:validates, field, presence: true)
    end 
  end
end

忽略将从超类继承的子类......

每次提交表单时,都会调用after_initialize并重复验证。

即。提交表格4次

输出:

field1 can't be blank
field1 can't be blank
field1 can't be blank
field1 can't be blank
field2 can't be blank
field2 can't be blank
field2 can't be blank
field2 can't be blank

有没有简单的方法只加载一次验证,而不是通过方法调用它们?

3 个答案:

答案 0 :(得分:0)

编辑:最后没有使用此解决方案。

嗯,任何人都有比这更好的解决方案吗?

class Foo < ActiveRecord::Base
  @@validations_ran = 0 
  FIELDS = [:field1, :field2]
  after_initialize :include_rules

  def include_rules
    if @@validations_ran != 1
      FIELDS.each do |field|
        self.class.send(:validates, field, presence: true)
      end 
      @@validations_ran = 1
    end
  end
end

答案 1 :(得分:0)

也许你可以使用一个关注点?

module Smoresable
  extend ActiveSupport::Concern

  included do
    validates :marshamallow, presence: true
    validates :graham, presence: true
    validates :chocolate, presence: true
  end
end

并在您的'子'类中使用它,如下所示:

class FooBar < ActiveRecord::Base
  include Smoresable
end

对于您想要自定义的类,只需添加您需要的类,如果列表足够短......或者与其他验证分组一起创建其他问题

答案 2 :(得分:0)

我走错了路。这就是我最终做的最终解决方案:

class Foo < ActiveRecord::Base
  self.abstract_class = true
  self.table_name = "foos"

  def self.defaults
    include_fields
    include_rules
  end

  def self.include_fields
    store :custom_fields, accessors: self::FIELDS
  end

  def self.include_rules
    self::FIELDS.each { |field| validates field, presence: true}
  end
end

class SubFoo < Foo
  FIELDS = [:bar, :bar1, :bar2] 
  defaults
end

现在我可以使用我可以选择包含或不包含的父默认验证来创建SubFoo实例。