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
。
希望这可以帮助。