mdr*_*iel 37 ruby validation activerecord ruby-on-rails
我想使用instance_eval增强现有的类.原始定义包含验证,需要存在某些字段,即:
class Dummy < ActiveRecord::Base
validates :field, :presence => true
end
Run Code Online (Sandbox Code Playgroud)
现在我想使用instance_eval(或任何其他方法,实际上)将其更改为可选:
Dummy.instance_eval do
...
end
Run Code Online (Sandbox Code Playgroud)
删除验证的正确语法是什么,因此该字段是可选的.我宁愿直接在模型层上执行此操作,而是在控制器或视图中执行奇怪的操作.实际上并不需要使用instance_eval,但据我所知,这通常是增强Rails中类的最佳方法.
编辑#1
一般来说 - 原始类是gem的一部分,我不想分叉它,也不想绑定到特定的版本.一般原因并不重要.简单地编辑原始模型比猴子修补具有更糟糕的后果.
Nic*_*roi 28
我找到了一个解决方案,不确定它有多坚固,但在我的情况下效果很好.@aVenger实际上接近他的回答.只是_validators访问者只包含用于反射的信息,而不包含实际的验证器回调!它们包含在_validate_callbacks访问器中,不要混淆_validations_callbacks.
Dummy.class_eval do
_validators.reject!{ |key, _| key == :field }
_validate_callbacks.reject! do |callback|
callback.raw_filter.attributes == [:field]
end
end
Run Code Online (Sandbox Code Playgroud)
这将删除所有验证器:field.如果您想更精确,可以拒绝与验证回调_validators的raw_filter访问者相同的特定验证器.
18a*_*gst 10
我认为这是目前最实际的解决方案(我使用的是rails 4.1.6):
# Common ninja
class Ninja < ActiveRecord::Base
validates :name, :martial_art, presence: true
end
# Wow! He has no martial skills
Ninja.class_eval do
_validators[:martial_art]
.find { |v| v.is_a? ActiveRecord::Validations::PresenceValidator }
.attributes
.delete(:martial_art)
end
Run Code Online (Sandbox Code Playgroud)
当我试图这样做以从狂欢地址模型中删除电话验证时,下面是我开始工作的代码.我添加了callback.raw_filter的类型检查,因为我只想删除电话字段上的状态验证器.我还必须添加它,因为它在尝试针对Spree :: Address模型中指定的其他验证器运行时会失败,该函数没有callback.raw_filter的'attributes'键,因此抛出异常.
Spree::Address.class_eval do
# Remove the requirement on :phone being present.
_validators.reject!{ |key, _| key == :phone }
_validate_callbacks.each do |callback|
callback.raw_filter.attributes.delete :phone if callback.raw_filter.is_a?(ActiveModel::Validations::PresenceValidator)
end
end
Run Code Online (Sandbox Code Playgroud)
我遇到了类似的问题,并且能够使用以下方法解决它:
class MyModel << Dummy
# erase the validations defined in the plugin/gem because they interfere with our own
Dummy.reset_callbacks(:validate)
...
end
Run Code Online (Sandbox Code Playgroud)
这是在 Rails 3.0 下。警告:它确实删除了所有验证,因此如果您想保留其他验证,您可以尝试Dummy.skip_callback(...),但我无法找出使该工作有效的参数的正确咒语。
| 归档时间: |
|
| 查看次数: |
12291 次 |
| 最近记录: |