验证与模型的错误消息相关联 [英] validates associated with model's error message

查看:64
本文介绍了验证与模型的错误消息相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个模型如下

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

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

Now when I associate an account to a user it says

帐号无效"

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

Instead I want to get the error message directly from that model. so it should say

应该至少有 3 个字符长!" or Already Taken" or 不能包含特殊字符"

有没有办法做到这一点?

is there a way to do this ?

我不想给出一个通用的信息:

I don't want to give a generic message like :

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

推荐答案

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

You can write your own custom validator, based on the code for the built-in validator.

查找 validates_related 的源代码,我们看到它使用了AssociatedValidator".其源代码是:

Looking up the source code for validates_associated, we see that it uses the "AssociatedValidator". The source code for that is:

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/associated_bubbling_validator.rb 中的初始值设定项):

So you can use this as an example to create a custom validator that bubbles error messages like this (for instance, add this code to an initializer in config/initializers/associated_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

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

So you can now validate like so:

class User < ActiveRecord::Base
 validates_associated_bubbling :account
end

另外,一定要在你的 has_many 关联中添加一个 validate: false ,否则,Rails 默认会验证这个关联,最终会出现两个错误消息,一种由新的 AssociatedBubblingValidator 提供,另一种由 Rails 提供.

Also, be sure to add a validate: false in your has_many association, otherwise, Rails will validate the association by default and you'll end up with two error messages, one given by your new AssociatedBubblingValidator and one generic given by Rails.

这篇关于验证与模型的错误消息相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆