【问题标题】:ActiveRecord - replace model validation error with warningActiveRecord - 用警告替换模型验证错误
【发布时间】:2010-07-27 09:58:29
【问题描述】:

我希望在 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 =&gt; false 默认值添加到ActiveRecord::Validations::ClassMethods::DEFAULT_VALIDATION_OPTIONS 通过扩展模块,但我正在寻找有关如何实现其余部分的一些见解。谢谢。

【问题讨论】:

    标签: ruby-on-rails validation activerecord extension-methods


    【解决方案1】:

    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。

    作者简要介绍了gem的开发on his blog

    【讨论】:

    【解决方案2】:

    我不知道它是否为 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 的新 Errors 对象和一个辅助方法 complete?,您可以将它添加到这样的模型中:

    class FollowupReport < ActiveRecord::Base
      validates :suggestions, :soft_validate => true
    end
    

    【讨论】:

      【解决方案3】:

      我制作了自己的 gem 来解决 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-20
        • 2018-01-16
        • 2017-03-08
        • 2012-02-18
        • 1970-01-01
        • 2017-01-22
        相关资源
        最近更新 更多