Rails custom validation error message not working - ruby-on-rails

My understanding is that I can customize error messages in the localization files. I'm currently trying to customize the error message for an invalid username field on my User model:
User.rb
class User < ActiveRecord::Base
validates :username, length: { within: 3..25 },
format: /\A(?=.*[a-z])[a-z\d]+\Z/i,
uniqueness: true
en.yml (localization file)
en:
activerecord:
errors:
models:
user:
attributes:
username:
format: "CUSTOM MESSAGE!"
The error message I receive, however, is the default "is invalid" message (or "Username is invalid" if I get the full_messages version).

Have a look here. There is no format key in the errors/messages. You need to override the invalid key.
en:
activerecord:
errors:
models:
user:
attributes:
username:
invalid: "CUSTOM MESSAGE!"

Related

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']

Rails validates doesn't accept custom message

I have the following validation:
validates :email, format: { with: Devise::email_regexp, message: I18n.t('activerecord.errors.models.client.attributes.email.invalid') }
The problem is, it is now showing the error message I specify there. It shows the default one.
What am I missing?
i18n should not be included in the model, but rather in a YAML file.
en:
activerecord:
errors:
models:
my_model:
attributes:
whatever:
inclusion: "Please select whatever." # see default key: "inclusion"
See more detailed answer about it here

Form validation message with aliased attribute name

I'm using Stripe within a model class. I have a strike_token attribute that I am validating presences of and creating a custom message like so:
validates :stripe_token, presence: { message: 'Please enter valid card info' }
When the form is submitted and not valid, the error message is, "Stripe token Please enter valid card info"
I don't want Stripe token in the error message. I have other validations as well that would be suited for the default, so I don't want to change the default error behavior.
It would be better if I could alias the Stripe token attribute to something like :card_info without actually having that as an attribute on the model.
So the message could be made to read, "Card info cannot be blank"
You can do as given below:
Just remove the :message part from validation.
# config/locales/en.yml
en:
activerecord:
attributes:
model_name:
stripe_token: ""
errors:
models:
model_name:
attributes:
stripe_token:
blank: "Card info cannot be blank!"
OR
# config/locales/en.yml
en:
activerecord:
attributes:
model_name:
stripe_token: "Card info"
errors:
models:
model_name:
attributes:
stripe_token:
blank: " cannot be blank!"
Replace model_name with your model name in small letters. Please check Fully custom validation error message with Rails for more details.
Update
# config/locales/en.yml
en:
activerecord:
attributes:
model_name:
stripe_token: "Card info"
Then use,
validates :stripe_token, presence: { message: ' cannot be blank!' }
Hope it helps :)

Can I specify a default error message format for a single validator across all attributes?

I know you can do this:
# config/locales/en.yml
en:
activerecord:
attributes:
user:
email: "E-mail address"
errors:
models:
user:
attributes:
email:
blank: "is required"
via https://stackoverflow.com/a/2859275/718050
Question 1
Is it possible to specify the message for blank across an entire model, or even sitewide, instead of going into every single attribute?
Question 2
Also, it seems that blank comes from :presence in the model, e.g.
validates :email, :presence => true
So if a :presence => true error translates to blank:, where can I find a list of these translations? How am I supposed to know what :unique => true turns into inside en.yml?
This list is here and here
as you can see you can redefine blank error like this:
en:
errors:
messages:
blank: "can't be blank"

Trouble on using the i18n gem with "resources of resources"

I am using Ruby on Rails 3.1 and I would like to know how to correctly handle internationalization related to "resources of resources". That is, ...
... in my config/routes.rb file I have:
resources :users do
resource :account
end
... in my app/models/users/account.rb file I have:
class Users::Account < ActiveRecord::Base
validates :firstname,
:presence => true
...
end
... in my config/locales/models/user/account/en.yml file I have:
en:
activerecord:
errors:
messages:
presence: "custom presence message - english"
... in my config/locales/models/user/account/it.yml file I have:
it:
activerecord:
errors:
messages:
presence: "custom presence message - italian"
The above code doesn't display in front end the "custom presence message" (it still displays the default RoR presence message: can not be blank). Furthermore if in my app/models/users/account.rb file I use:
class Users::Account < ActiveRecord::Base
validates :firstname,
:presence => { :message => t(:presence) } # Here I try to use the i18n helper method
...
end
I get the following error:
NoMethodError (undefined method `t' for #<Class:0x000001075bbc80>)
Why I get the NoMethodError?
Is the problem related to how I am organizing in directories my locale files? At this time (as stated in the official RoR guide) my file system is:
config/locales/defaults/en.yml
config/locales/defaults/it.yml
config/locales/models/user/en.yml
config/locales/models/user/it.yml
config/locales/models/user/account/en.yml
config/locales/models/user/account/it.yml
In few words, I would like to display my "custom presence message" only on validating "resources of resources" kind of Users::Account. How can I do that?
I also tried to state the following code in the config/locales/models/user/account/en.yml file
en:
activerecord:
errors:
models:
user:
account:
attributes:
firstname:
blank: "custom presence message - english"
but it doesn't work. Anyway the following works but I need different translations for different attributes (as I tried to state in the previous code example):
en:
activerecord:
errors:
messages:
blank: "custom presence message - english"
ok, due to this: https://github.com/rails/rails/issues/1402 last comment nested model look-up is removed
so try maybe something like
activerecord:
errors:
models:
users:
account:
attributes:
first_name:
blank: "You should fill up first name field to complete that"
and change inside :message hash to
I18n.t(:"activerecord.errors.models.users.account.attributes.first_name.blank")
and try avoid nested models ;-)
update:
after some debuging this will work:
activerecord:
errors:
models:
"users/account":
attributes:
first_name:
blank: "You should fill up first name field to complete that"

Resources