Overwrite Rails validation message - ruby-on-rails

How do you overwrite a validation message in Rails?
Even if I pass in a proc like so..
validates :my_item, uniqueness: {
scope: [:name, :type],
message: -> (object, data) do
"This item is already taken"
end,
}
It still appends the [object] to the front of the message. So that is reads: "[name of the object] This item is already taken"
Edit:
Also have tried adding a ^ to the beginning of message. Still does not work.
"^This item is already taken"

Instead of trying to override it at the model level, just leverage the fact that you're essentially trying to tweak the en locale.
In config/locales/en.yml you should be able to do something like this:
en:
activerecord:
errors:
messages:
taken: "This item is already taken."
models:
my_item:
taken: "This item is already taken."
I haven't tested this config directly, but the messages key should change the message for all models. Otherwise you can specify the message on a per-model basis. I don't believe that this will include the object name. You can find a list of the field names in the Rails Internationalization Guide.

Related

Overwrite rails error message format only for custom error messages

Is there a way to overwrite the message format only for custom error messages?
I know that it is possible to overwrite rails error message formats at the attribute and model level by using
en:
errors:
format: '%{message}'
or
en:
activemodel:
errors:
models:
person:
format: '%{message}'
or
en:
activemodel:
errors:
models:
person:
attributes:
name:
format: '%{message}'
source (https://github.com/rails/rails/pull/32956).
The issue with this approach, no matter which level the format is overwritten at, this always overwrites the format for all default rails error messages.
If I have a model Person with an attribute name and I add a en.yml config like
en:
activemodel:
errors:
models:
person:
attributes:
name:
older_than_eighteen: "You must be older than eighteen"
format: '%{message}'
this now leads to all error message for the name attribute of person being interpolated without the attribute name. If I got some validate :name, presence: true the error message for a blank name becomes can't be blank instead of Name can't be blank.
I know that I could add another error message to the en.yml file above like blank: "Name can't be blank" but I would like to avoid that and instead only change the format for my custom error message.
Is there a way to achieve this?
add into your config/application.rb
config.active_model.i18n_customize_full_message = true
According to the RoR official docs:
Controls whether the Error#full_message format can be overridden in an i18n locale file. Defaults to false.
When set to true, full_message will look for a format at the attribute and model level of the locale files. The default format is "%{attribute} %{message}", where attribute is the name of the attribute, and message is the validation-specific message. The following example overrides the format for all Person attributes, as well as the format for a specific Person attribute (age).

ActiveRecord Validations : String added to error message in locales

I'm trying customize validation error messages using i18n.
Let's say I have an Address model that validates the presence of a zip_code.
My config/locales/activerecord.fr.yml looks like this
fr:
activerecord:
errors:
models:
address:
attributes:
civility:
blank: "Some message"
The issue if I fail the validation, the error message I'l have in #address.errors.full_messages will be:
"Zip code Some message"
Why does Zip code gets added to my error message ? And how can I avoid this behaviour ?
You can just add:
errors:
format: "%{message}"
This way you will just show error message with out attribute name.
Edit: this should be added to config/locales/fr.yml and not config/locales/activerecord.fr.yml (which also has errors:)
Found a gem which will solve your purpose
With the help of this gem, You just need to start the locale message with a caret and it shouldn't display the attribute name in the message.
A model defined as:
class Item < ApplicationRecord
validates :name, presence: true
end
with the following en.yml:
en:
activerecord:
errors:
models:
item:
attributes:
name:
blank: "^You can't create an item without a name."
item.errors.full_messages will display:
#You can't create an item without a name
instead of the usual
#Name You can't create an item without a name
You could simply use:
#address.errors.messages[:zip_code] # or #address.errors[:zip_code]
#=> ['Some message']

Error messages in nested attribute

I've three models called Account,User and AccountPermission.
I'm creating the Account via AccountPermission while creating user.
However, If a problem occurs related with Account :name, the system throws something like that below.
Account permissions account name has already been taken
So, I just need to fix this error message.
I've tried to add a message attribute to my validation. It is just appending to actual message.
I've also tried locale thing. Still just appending
en:
activerecord:
errors:
models:
account:
attributes:
name:
taken: 'bla bla'
As far as I see in ActiveModel. This message's structure comes from below
locale/en.yml in ActiveModel
en:
errors:
format: "%{attribute} %{message}"
So, Is there any way edit this message painless ? If I even delete the model name, It's enough.
Error message is concatenated from the error itself and the attribute name, which is account_permissions/account.name in the provided error.
You can add locale for your attribute names like so:
en:
activerecord:
attributes:
account: # this is model name
name: "Name"
or
en:
activerecord:
attributes:
account_permissions/account:
name: "Account name"

Rails 3 Customer Error message

I'm trying to do something very simple. I have a validates presence of in rails 3:
validates_presence_of [:first_nm]
When this fires, it gives the following crappy message:
"first nm cannot be blank"
I want to override the error message to give a friendly field name for "first nm"
"Please fill out your First Name"
I have seen all kinds of plugins, localization, humanized attributes tutorials, but these don't seem to work or are outdated. Is there no simple way to do this in Rails 3?
For localization, i've tried this:
# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
activerecord:
errors:
messages:
taken: "has already been taken"
record_invalid: "Validation failed: %{errors}"
models:
customer:
blank: "This is a custom blank message for %{model}: %{attribute}"
attributes:
first_nm:
blank: "This is a custom blank message for first name"
Alas, no luck. My error message did not change.
On thing that might be related. I'm not inheriting from ActiveRecord, because this object is getting saved via soap, not database. Instead, I have the following:
class Customer
extend ActiveModel::Naming
include ActiveModel::Conversion
include ActiveModel::Validations
end
Have you seen this page on ActiveRecord localization? It seems to be for Rails 3. I can't test it right now, but by the document it seems you can do:
models.user.attributes.first_nm.blank = "Please fill out your First Name"

Ruby on Rails: controlling the layout of an error message in ActiveRecord

My error messages in Rails look like the following:
"Email Your email is invalid."
Why is the name of the field prefixed within the string itself? It makes the error messages look awfully odd.
Is there anyway to circumvent this behavior so that I can just see "Your email is invalid."
The documentation for generate_full_message might be of use:
The default full_message format for any locale is "{{attribute}} {{message}}". One can specify locale specific default full_message format by storing it as a translation for the key: "activerecord.errors.full_messages.format".
Additionally one can specify a validation specific error message format by storing a translation for: "activerecord.errors.full_messages.[message_key]". E.g. the full_message format for any validation that uses :blank as a message key (such as validates_presence_of) can be stored to: "activerecord.errors.full_messages.blank".
Because the message key used by a validation can be overwritten on the validates_* class macro level one can customize the full_message format for any particular validation:
# app/models/article.rb
class Article < ActiveRecord::Base
validates_presence_of :title, :message => :"title.blank"
end
# config/locales/en.yml
en:
activerecord:
errors:
full_messages:
title:
blank: This title is screwed!
In your case, since you're using the default {{attribute}} {{message}} format, you're getting "Email" for the attribute and "Your email is invalid" as the message. You could change the :message argument to "is not a valid format" and you should get "Email is not a valid format". That's the quick fix. If you want to fully customize it you can use the locale method above.

Resources