验证与模型的错误消息相关联 [英] validates associated with model's error message
问题描述
我有两个模型如下
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屋!