Ori*_*rds 19 validation ruby-on-rails callback single-table-inheritance
给定一个模型
class BaseModel < ActiveRecord::Base
validates_presence_of :parent_id
before_save :frobnicate_widgets
end
Run Code Online (Sandbox Code Playgroud)
和派生模型(底层数据库表有一个type字段 - 这是简单的rails STI)
class DerivedModel < BaseModel
end
Run Code Online (Sandbox Code Playgroud)
DerivedModel将以良好的OO方式继承所有的行为BaseModel,包括validates_presence_of :parent_id.我想关闭验证DerivedModel,并防止回调方法被触发,最好不要修改或以其他方式破坏BaseModel
什么是最简单,最强大的方法?
小智 45
我喜欢使用以下模式:
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
Run Code Online (Sandbox Code Playgroud)
如果rails提供了skip_validation方法来解决这个问题会很好,但是这种模式可以很好地处理复杂的交互.
作为@Jacob Rothstein的答案的变体,您可以在父中创建一个方法:
class Parent < ActiveRecord::Base
validate_uniqueness_of :column_name, :unless => :child?
def child?
is_a? Child
end
end
class Child < Parent
end
Run Code Online (Sandbox Code Playgroud)
这种方法的好处是您不需要为在Child类中禁用验证所需的每个列名创建多个方法.
通过浏览源代码(我目前使用的是 Rails 1.2.6),回调相对简单。
事实证明before_validation_on_create,before_save等方法,如果不使用任何参数调用,将返回包含分配给该“回调站点”的所有当前回调的数组
要清除 before_save 的,你可以简单地做
before_save.clear
Run Code Online (Sandbox Code Playgroud)
这似乎有效