代码之家  ›  专栏  ›  技术社区  ›  Orion Edwards

如何在rails STI派生模型中禁用验证和回调?

  •  17
  • Orion Edwards  · 技术社区  · 16 年前

    class BaseModel < ActiveRecord::Base
      validates_presence_of :parent_id
      before_save :frobnicate_widgets
    end
    

    和派生模型(底层数据库表有 type

    class DerivedModel < BaseModel
    end
    

    DerivedModel 会很好地继承 BaseModel ,包括 validates_presence_of :parent_id . 我想关闭验证 派生模型 基本模型

    7 回复  |  直到 16 年前
        1
  •  45
  •   Jacob Rothstein Jacob Rothstein    15 年前

    我喜欢使用以下模式:

    class Parent < ActiveRecord::Base
      validate_uniqueness_of :column_name, :if => :validate_uniqueness_of_column_name?
      def validate_uniqueness_of_column_name?
        true
      end
    end
    
    class Child < Parent
      def validate_uniqueness_of_column_name?
        false
      end
    end
    

    如果rails提供了一个skip_验证方法来解决这个问题,那就太好了,但是这个模式可以很好地工作并处理复杂的交互。

        2
  •  9
  •   Chandresh Pant    12 年前

    作为@Jacob Rothstein答案的变体,您可以在parent中创建一个方法:

    class Parent < ActiveRecord::Base
      validate_uniqueness_of :column_name, :unless => :child?
      def child?
        is_a? Child
      end
    end
    
    class Child < Parent
    end
    

        3
  •  3
  •   Orion Edwards    16 年前

    从源代码(我目前在rails 1.2.6上)中查找,回调相对简单。

    结果发现 before_validation_on_create before_save etc方法,如果没有用任何参数调用,将返回包含分配给该“回调站点”的所有当前回调的数组

    要清除之前保存的文件,只需执行以下操作

    before_save.clear
    

    而且似乎很管用

        4
  •  2
  •   phlegx    9 年前

    class Parent < ActiveRecord::Base
      validate :column_name, uniqueness: true, if: 'self.class == Parent'
    end
    
    
    class Child < Parent
    end
    

    或者也可以这样使用:

    class Parent < ActiveRecord::Base
      validate :column_name, uniqueness: true, if: :check_base
    
      private
    
      def check_base
        self.class == Parent
      end
    end
    
    
    class Child < Parent
    end
    

    因此,如果模型的实例类是 Parent .

    1. 实例类 Child 不同于 起源 .
    2. 实例类 起源 起源 .
        5
  •  2
  •   ulferts    7 年前

    由于Rails3.0,您还可以访问 validators class method 操作获取所有验证的列表。但是,不能通过此数组操作验证集。

    _validators (未记录的)方法。

    使用此方法,您可以修改子类中的验证,例如:

    class Child < Parent
      # add additional conditions if necessary
      _validators.reject! { |attribute, _| attribute == :parent_id } 
    end
    

        6
  •  0
  •   Orion Edwards    16 年前

    再次在源代码中查找,似乎验证可以在每次保存时运行,也可以仅在更新/创建时运行。这个映射到

    :validate =>全部保存
    :validate_on_create
    :validate_on_update =>仅更新

    要清除它们,可以使用 write_inheritable_attribute ,就像这样:

    write_inheritable_attribute :validate, nil
    
        7
  •  0
  •   hadees    11 年前

    mongoid 3 .

    class Parent
      include Mongoid::Document
      validates :column_name , uniqueness: true, unless: Proc.new {|r| r._type == "Child"}
    end
    
    class Child < Parent
    end
    

    到目前为止,它对我很有帮助。