ActiveRecord - 用警告替换模型验证错误

sa1*_*125 10 validation extension-methods activerecord ruby-on-rails

我希望能够在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
Run Code Online (Sandbox Code Playgroud)

知道如何实现这个吗?我能够 通过扩展模块添加:warning => false默认值ActiveRecord::Validations::ClassMethods::DEFAULT_VALIDATION_OPTIONS,但我正在寻找有关如何实现其余部分的一些见解.谢谢.

Ken*_*enB 5

validation_scopes宝石使用了一些很好的元编程魔术给你所有的验证和ActiveRecord的::错误对象的常用功能比object.errors其他上下文.

例如,您可以说:

validation_scope :warnings do |s|
  s.validates_presence_of :some_attr
end
Run Code Online (Sandbox Code Playgroud)

上面的验证将像往常一样在object.valid?上触发,但如果some_attr不存在,则不会阻止对object.save上的数据库的保存.任何关联的ActiveRecord :: Errors对象都可以在object.warnings中找到.

以通常方式指定的没有作用域的验证仍将按预期运行,阻止数据库保存并将错误对象分配给object.errors.

作者在他的博客上简要描述了宝石的发展.


kwe*_*ous 4

I don't know if it's ready for Rails 3, but this plugin does what you are looking for:

http://softvalidations.rubyforge.org/

Edited to add:

To update the basic functionality of this with ActiveModel I came up with the following:

#/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
Run Code Online (Sandbox Code Playgroud)

It adds a new Errors like object called warnings and a helper method complete?, and you can add it to a model like so:

class FollowupReport < ActiveRecord::Base
  validates :suggestions, :soft_validate => true
end
Run Code Online (Sandbox Code Playgroud)