我正在编写一个库,需要以编程方式将验证从一个模型复制到另一个模型,但我很难知道如何解决这个问题。
我有一个ActiveModel::Model
的模型,有一些验证:
class User < ActiveRecord::Base
validates :name, presence: true
end
另一个我希望获得相同验证的模型:
class UserForm
include ActiveModel::Model
attr_accessor :name
end
现在,我希望UserForm
提供与User
相同的验证,而无需修改User
。复制验证器不起作用,因为ActiveModel::Validations
在验证检查期间挂钩回调:
UserForm._validators = User._validators
UserForm.new.valid?
# => true # We wanted to see `false` here, but no validations
# are actually running because the :validate callback
# is empty.
不幸的是,似乎并不是一种简单的方法,我可以通过编程方式为一个模型提供另一个验证回调并且仍然有效。我认为我最好的选择是,如果我可以让Rails根据给定时刻出现的验证器重新生成验证回调。
这可能吗?如果没有,有更好的方法吗?
答案 0 :(得分:0)
检查activerecord/lib/active_record/validations/presence.rb
的代码可以了解如何实现这一目标:
# File activerecord/lib/active_record/validations/presence.rb, line 60
def validates_presence_of(*attr_names)
validates_with PresenceValidator, _merge_attributes(attr_names)
end
所以我想我会尝试使用alias_method
挂钩validates_with
alias_method :orig_validates_with :validates_with
现在您有机会获得传递的值,因此您可以将它们存储在某处并在需要在UserForm
alias_method :orig_validates_with, :validates_with
def validates_with(*args)
# save the stuff you need, so you can recreate this method call on UserForm
orig_validates_with(*args)
end
然后您应该可以致电UserForm.validates_with(*saved_attrs)
。对不起,这不是你可以复制/粘贴的东西,但这应该让你开始。 HTH