我希望能够在rails中保存/更新模型时用警告替换字段错误。基本上我想只是编写一个包装器,围绕验证方法生成错误,保存模型,也许可以在警告哈希中使用(就像错误哈希一样):
class Person < ActiveRecord::Base
# normal validation
validates_presence_of :name
# validation with warning
validates_numericality_of :age,
:only_integer => true,
:warning => true # <-- only warn
end
>>> p = Person.new(:name => 'john', :age => 2.2)
>>> p.save
=> true # <-- able to save to db
>>> p.warnings.map { |field, message| "#{field} - #{message}" }
["age - is not a number"] # <-- have access to warning content
知道如何实现这个吗?我能够将:warning => false
默认值添加到ActiveRecord::Validations::ClassMethods::DEFAULT_VALIDATION_OPTIONS
通过扩展模块,但我正在寻找有关如何实现其余部分的一些见解。感谢。
答案 0 :(得分:5)
validation_scopes gem使用了一些不错的元编程魔法来为你提供验证的所有常用功能以及除object.errors之外的上下文中的ActiveRecord :: Errors对象。
例如,您可以说:
validation_scope :warnings do |s|
s.validates_presence_of :some_attr
end
上面的验证将像往常一样在object.valid?上触发,但如果some_attr不存在,则不会阻止对object.save上的数据库的保存。任何关联的ActiveRecord :: Errors对象都可以在object.warnings中找到。
以通常方式指定的没有作用域的验证仍将按预期运行,阻止数据库保存并将错误对象分配给object.errors。
作者简要介绍了宝石的发展on his blog。
答案 1 :(得分:4)
我不知道它是否已准备好用于Rails 3,但此插件可以满足您的需求:
http://softvalidations.rubyforge.org/
编辑添加:
要使用ActiveModel更新此基本功能,我想出了以下内容:
#/config/initializer/soft_validate.rb:
module ActiveRecord
class Base
def warnings
@warnings ||= ActiveModel::Errors.new(self)
end
def complete?
warnings.clear
valid?
warnings.empty?
end
end
end
#/lib/soft_validate_validator.rb
class SoftValidateValidator < ActiveModel::EachValidator
def validate(record)
record.warnings.add_on_blank(attributes, options)
end
end
它添加了一个新的错误类似对象 warnings 和一个帮助方法完成?,你可以将它添加到这样的模型中:
class FollowupReport < ActiveRecord::Base
validates :suggestions, :soft_validate => true
end
答案 2 :(得分:1)
我制作了自己的宝石来解决Rails 4.1+的问题:https://github.com/s12chung/active_warnings
class BasicModel
include ActiveWarnings
attr_accessor :name
def initialize(name); @name = name; end
warnings do
validates :name, absence: true
end
end
model = BasicModel.new("some_name")
model.safe? # .invalid? equivalent, but for warnings
model.warnings # .errors equivalent