validation与模型的错误消息相关联

我有两个模型如下

class User < ActiveRecord::Base validates_associated :account end class Account  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 

现在,当我将帐户与用户关联时,它说

“帐户无效”

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

"Should be atleast 3 characters long!""Already Taken"" Cannot contain special charaters"

有没有办法做到这一点 ?

我不想给出如下通用消息:

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

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

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

 module ActiveRecord module Validations class AssociatedValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) return if (value.is_a?(Array) ? value : [value]).collect{ |r| r.nil? || r.valid? }.all? record.errors.add(attribute, :invalid, options.merge(:value => value)) end end module ClassMethods def validates_associated(*attr_names) validates_with AssociatedValidator, _merge_attributes(attr_names) end end end end 

因此,您可以使用此示例来创建一个自定义validation程序,它会冒泡错误消息,如下所示:

 module ActiveRecord module Validations class AssociatedBubblingValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) (value.is_a?(Array) ? 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 

您可以将此代码放在初始化程序中,例如/initializers/associated_bubbling_validator.rb

最后,你会这样validation:

 class User < ActiveRecord::Base validates_associated_bubbling :account end 

注意:上面的代码是完全未经测试的,但是如果它不能完全正常工作,那么希望能让你走上正确的轨道

也许你可以尝试下面给出的东西

 validates_associated :account , :message=> lambda{|class_obj, obj| obj[:value].errors.full_messages.join(",") } 

通过obj[:value]您将访问经过validation的Account对象。 所以obj [:value] .errors会给你错误。

一个vanilla解决方案是对关联对象进行第二次错误渲染:

 <%= render :partial => 'shared/errors', :locals => {:instance => @account.owner} %> <%= render :partial => 'shared/errors', :locals => {:instance => @account} %> 

要获取帐户的错误消息,您必须在该实例上调用errors方法:

 @user.account.errors 

要么

 @account = @user.build_account @account.errors 

或者在视图中:

 <%= error_messages_for :account %> 

我假设它是一个has_one关系。

我遇到了同样的问题……我想validation关联的对象,并且valid? 方法返回false,但不添加“帐户无效”之类的(多余的)消息。 我只希望帐户validation消息显示在帐户字段旁边。

我发现完成此任务的唯一方法是覆盖run_validations! ,如下。 在此示例中,关联是has_many :contacts

 def run_validations! valid = super contacts.each do |contact| valid = false unless contact.valid?(validation_context) end valid end 

不要使用valid &&= contacts.all? ... valid &&= contacts.all? ...因为如果基类已经无效,这将阻止对联系人的validation,并且如果其中一个联系人未通过validation,则将停止迭代。

也许这是一个想法,将其概括为一些关注模块,但我只需要它一次。

对于仍在Rails 2上的用户,可以使用以下代码覆盖validates_associated:

 module ActiveRecord::Validations::ClassMethods def validates_associated(association, options = {}) class_eval do validates_each(association) do |record, associate_name, value| associate = record.send(associate_name) if associate && !associate.valid? associate.errors.each do |key, value| record.errors.add(key, value) end end end end end end 

资料来源: http : //pivotallabs.com/alias-method-chain-validates-associated-informative-error-message/

如果无论如何需要它,下面的工作在Rails 5.2上

 #app/validators/with_own_error_messages_validator.rb class WithOwnErrorMessagesValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) Array(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 #app/models/project.rb class Project < ApplicationRecord validates :attachments, with_own_error_messages: true has_many :attachments, as: :attachable, validate: false end 

请注意has_many关联上的validate: false 。 这是必要的,因为Rails现在默认validation关联。 如果没有它,您将收到Attachment错误消息以及通用Attachments is invalid

希望这可以帮助。