Errors.add, setting the whole message

Hi all. I have an attribute, job_role_id_short, that is being set in a
form. This field has a custom validation on it, which does this if it
fails:

self.errors.add(:job_role_id_short, “cannot be blank”)

I want to add the error onto the attribute, so that the form builder
will wrap the field in a fieldWithErrors div. However, the error it
generates says “Job Role Short cannot be blank”. I’d like it to say
“Job cannot be blank”.

Is there a way of adding an error to a specific attribute that will let
me set the whole error message, not just the last part of it?

thanks, max

If you’re using I18n (which I think is always a good idea, even if
you’re only using one language) you can do two things:

  1. Define a translation for the job_role_id_short attribute:

In app_root/config/locales/en.yml:

en:
activerecord:
attributes:
my_model:
job_role_id_short: “Job”

This will not only fix “Job Role Short” in the error message but
anywhere else where Rails tries to convert that attribute in a human
readable string. If you dont want this, go for the alternative:

  1. Override the default error message for this kind of error on this
    particular attribute (Also see documentation for
    generate_full_message (ActiveRecord::Error) - APIdock):

In app_root/config/locales/en.yml:

en:
activerecord:
errors:
full_messages:
job_role_id_short:
blank: “Job cannot be blank”

Sjoerd A. wrote in post #943536:

  1. Override the default error message for this kind of error on this
    particular attribute (Also see documentation for
    generate_full_message (ActiveRecord::Error) - APIdock):

In app_root/config/locales/en.yml:

en:
activerecord:
errors:
full_messages:
job_role_id_short:
blank: “Job cannot be blank”

Thanks Sjoerd but i can’t get this working: i put this in my
config/locales/en.yml file:

en:


activerecord:
errors:
full_messages:
password:
blank: “Something about the password being missing”
invalid: “Something about the password not being valid”

Then in my controller, i do

  @user_session.errors.add(:password) #use default of :invalid

And i get “Password is invalid” back. This is in rails 2.3.4.

thanks, max

Sjoerd A. wrote in post #949766:

It seems this feature has been added in 2.3.5

(rails/activerecord/lib/active_record/validations.rb at v2.3.5 · rails/rails · GitHub).

I’d recommend upgrading as Im not aware of an easy alternative way of
doing this.

Thanks Sjoerd, i might upgrade if needs be. I’ve been looking in
./vendor/rails/activerecord/lib/active_record/locale/en.yml though and
it looks like i should be able to change the basic format for all error
messages: it has this line

en:
activerecord:
errors:
full_messages:
format: “{{attribute}} {{message}}”

Which i thought would mean i could change it to

    format: "{{message}}"

which would globally remove the attribute name from the start of all
errors, which is fine as i can add it back in on an
attribute-by-attribute basis or stick with custom messages for
everything.

But, it doesn’t work. I’ll keep hacking away…

cheers, max

Here you can see how the ‘full_messages.format’ scope is applied:

Maybe it’ll give you some insight in why it’s not working. Perhaps
I18n.t’s :default option is overridden? Good luck!

Sjoerd A. wrote in post #949781:

Perhaps I18n.t’s :default option is overridden?
Forget about that, it merges the default scope into the options hash so
it always takes precedence.

It seems this feature has been added in 2.3.5
(rails/activerecord/lib/active_record/validations.rb at v2.3.5 · rails/rails · GitHub).
I’d recommend upgrading as Im not aware of an easy alternative way of
doing this.

Sjoerd A. wrote in post #949781:

Here you can see how the ‘full_messages.format’ scope is applied:

Maybe it’ll give you some insight in why it’s not working. Perhaps
I18n.t’s :default option is overridden? Good luck!

I figured it out, it’s not to do with I18n at all as it happens. It was
because i’d overriden the ActionView::Base.field_error_proc method to
wrap my errored fields in some different markup to the default, and this
was pulling in the attribute name and the error message. So, the error
message was right all along, it was my markup generator that was wrong.
In case anyone’s interested, this is what i have now:

#override the logic/html for wrapping fields in fieldWithErrors divs in
form_for
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
if html_tag =~ /^<label\s/
html_tag
else
error_message = instance.error_message.collect{|m| “#{m}”}.join(",
")
“<div class="fieldWithErrors">

#{error_message}
#{html_tag}”
end
end

Thanks for all your help Sjoerd
max