Rails 4: remove attribute name from error message in custom validator

寵の児 提交于 2020-01-16 04:30:26

问题


In my Rails 4 app, I implemented a custom validator named LinkValidator on my Post model:

class LinkValidator < ActiveModel::Validator

  def validate(record)
    if record.format == "Link"
      if extract_link(record.copy).blank?
        record.errors[:copy] << 'Please make sure the copy of this post includes a link.'
      end
    end
  end

end

Everything works fine, except that currently, the message displayed is:

1 error prohibited this post from being saved:
Copy Please make sure the copy of this post includes a link.

How can remove the word "copy" from the above message?

I tried record.errors << '...' instead of record.errors[:copy] << '...' in the validator, but then the validation no longer works.

Any idea?


回答1:


Unfortunately currently the format of full_messages for errors is controlled with a single I18n key errors.format, hence any change to it will have a global consequences.

Common option is to attach error to the base rather than to the attribute, as full messages for base errors do not include attribute human name. Personally I don't like this solution for number of reason, main being that if the validation error is caused by a field A, it should be attach to field A. It just makes sense. Period.

There is no good fix for this problem though. Dirty solution is to use monkey patching. Place this code in a new file in your config/initializers folder:

module ActiveModel
  class Errors
    def full_message(attribute, message)
      return message if attribute == :base
      attr_name = attribute.to_s.tr('.', '_').humanize
      attr_name = @base.class.human_attribute_name(attribute, :default => attr_name)
      klass = @base.class
      I18n.t(:"#{klass.i18n_scope}.error_format.#{klass.model_name.i18n_key}.#{attribute}", {
                                 :default   => [:"errors.format", "%{attribute} %{message}"],
                                 :attribute => attr_name,
                                 :message   => message
                             })
    end
  end
end

This preserves the behaviour of full_messages (as per rails 4.0), however it allows you to override the format of full_message for particular model attribute. So you can just add this bit somewhere in your translations:

activerecord:
  error_format:
    post:
      copy: "%{message}"

I honestly dislike the fact that there is no clean way to do this, that probably deserves a new gem.



来源:https://stackoverflow.com/questions/34347128/rails-4-remove-attribute-name-from-error-message-in-custom-validator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!