ruby-on-rails - 验证与模型的错误消息关联

标签 ruby-on-rails validation

我有两个模型如下

class User < ActiveRecord::Base
 validates_associated :account
end

class Account < ActiveRecord::Base

  belongs_to :user

  #----------------------------------Validations--Start-------------------------
  validates_length_of :unique_url, :within => 2..30 ,:message => "Should be atleast 3 characters long!"
  validates_uniqueness_of :unique_url ,:message => "Already Taken"
  validates_format_of :unique_url,:with => /^([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])$/ , :message => " Cannot contain special charaters"
  #----------------------------------Validations--End---------------------------
end

现在,当我将帐户与用户关联时,它会显示

"Account is invalid"

相反,我想直接从该模型获取错误消息。 所以应该说

“长度至少应为 3 个字符!”“已使用”“不能包含特殊字符”

有办法做到这一点吗?

我不想给出像这样的通用消息:

validates_associated :account , :message=>"one of the three validations failed"

最佳答案

您可以根据内置验证器的代码编写自己的自定义验证器。

查找 validates_linked 的源代码,我们看到它使用“AssociatedValidator”。其源代码是:

module ActiveRecord
  module Validations
    class AssociatedValidator < ActiveModel::EachValidator
      def validate_each(record, attribute, value)
        if Array.wrap(value).reject {|r| r.marked_for_destruction? || r.valid?}.any?
          record.errors.add(attribute, :invalid, options.merge(:value => value))
        end
      end
    end

    module ClassMethods
      
      def validates_associated(*attr_names)
        validates_with AssociatedValidator, _merge_attributes(attr_names)
      end
    end
  end
end

因此,您可以以此为示例来创建一个自定义验证器,该验证器会像这样冒泡错误消息(例如,将此代码添加到 config/initializers/linked_bubbling_validator.rb 中的初始值设定项中):

module ActiveRecord
  module Validations
    class AssociatedBubblingValidator < ActiveModel::EachValidator
      def validate_each(record, attribute, value)
        ((value.kind_of?(Enumerable) || value.kind_of?(ActiveRecord::Relation)) ? value : [value]).each do |v|
          unless v.valid?
            v.errors.full_messages.each do |msg|
              record.errors.add(attribute, msg, options.merge(:value => value))
            end
          end
        end
      end
    end

    module ClassMethods
      def validates_associated_bubbling(*attr_names)
        validates_with AssociatedBubblingValidator, _merge_attributes(attr_names)
      end
    end
  end
end

所以你现在可以像这样验证:

class User < ActiveRecord::Base
 validates_associated_bubbling :account
end

此外,请务必在您的 has_many 关联中添加 validate: false,否则,Rails 将默认验证关联,最终会出现两个错误消息,一种由新的 AssociatedBubblingValidator 给出,另一种由 Rails 给出。

关于ruby-on-rails - 验证与模型的错误消息关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7387459/

相关文章:

Javax 验证 : Constraint Violations for Map

ruby-on-rails - 我如何处理 View 中的 nils?

ruby-on-rails - Rails 3 respond_with json 问题

javascript - angularJS 中的客户端重复数据验证

C++ 验证循环问题

javascript - 如何在 react 输入中仅允许数字和小数

Silverlight 验证消息位置

ruby-on-rails - 需要澄清 Ruby 状态机的使用

mysql - RailsReady 中未包含的内容?

jquery - 格式错误的 Rails JSON 和 jQuery