0

我想要一个具有默认验证的超类和可以覆盖默认验证的子类。

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

有什么简单的方法可以只加载一次验证,但在方法中调用它们?

4

3 回答 3

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 实例。

于 2013-08-23T18:20:29.743 回答
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

对于您想要自定义它的类,只需添加您需要的类,如果列表足够短......或者对其他验证分组创建额外的关注点

于 2013-08-23T00:45:47.860 回答
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
于 2013-08-22T20:40:04.780 回答