Rails: Changing Error Messages - ruby-on-rails

My error messages are not showing automatically, so I decided to use flash as a workaround. This is what I'm doing
Controller:
flash[:notice] = #post.errors.full_messages
View:
<%= flash[:notice] %>
Then, I get this ugly error message on my view.
["Content can't be blank", "Content is too short (minimum is 10 characters)"]
But at least, the user successfully gets the error message. Now I need to customize the error message and make it look a little bit more pretty. I guess I could parse each error sentence into some local variables and show them (is there a more sophisticated way?). However, I don't know how to customize the error message. For example, "Content can't be blank" should be changed to "You left the content blank". Where can I fix this?

What happens is that when #post contains some validation errors doing #post.errors.full_messages returns an array of errors that happened during validation.
To display them nicely you might want to do something like
<%- flash[:notice].each do |error| %>
<%= error %>
<% end %>
EDIT
Whoops I misread the question.
These errors are validation errors in your model where you have the validations like
validates you can pass custom messages like so
validates :content, :presence => { :message => "You left the content blank" }
Update: check this link out for the options you have
http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates

Related

Add certain text to the end of any validation error message

I want to add 'Notice that you have to select all the images and related vehicles again.' to the end of any validation error, regardless of how many errors there are, so for example adding this text to the end of every error message isn't an option, because it will be shown many times if there is more than one error.
Is there any way to add particular text to the end of validation error message?
Tried to google but didn't found anything.
This is easily accomplished however it may be tedious depending on how many validations you have listed. I will give some examples so you can decide on what best suites your needs:
If using Rails' built-in validations (such as prescence, uniqueness, etc.) you can add your own message inside the validation along with the standard output or replace it completely with your own:
validates :username, :email, :title, :another_attribute,:omg_another_attribute, :password, presence: { :message => "cant be blank. Notice that you have to select all the images and related vehicles again for not filling out the form ya dumbo!"}
This will list the error message for every field they left blank. If you want to add an error just once at the end of all the error messages to remind them of this problem you can make a custom validation that checks for other errors and then appends its own, one time, at the end like:
#Make sure to put this custom validate method after all the other validators since they are run in order from top to bottom and you want to see if the others have failed
validate :add_blanket_error_when_one_or_more_errors_happen
def add_blanket_error_when_one_or_more_errors_happen
if self.errors.count > 0 then self.errors.add(:base, "Notice you were being dumb again and now have to fill more stuff out.") end
end
I normally add generic errors like this to the 'base' field but you can attach it to any field in your form if you dont want to add extra styling/markup. In your view if you chose to add it to the 'base' field you can put this message right at the top of the form if it exists by doing:
<% unless #the_form_object_youre_using_here.errors[:base].blank? %>
<div>
<span class="error-explanation"><%= #again_the_form_object_here.errors[:base].first %></span>
</div>
<% end %>
This will also let you style the span etc.
Unfortunately there is no simple one-liner you can add to your model to append a blanket message to all failed validations. Even trying something seemingly harmless like a custom validation to accomplish it(DONT TRY THIS UNLESS YOU HAVE your task-manager ready because it will cause a memory leak and even make your computer crash if you dont kill the process quickly)
**DONT DO IT IF YOU ENJOY COORS LIGHT OR PREFER LONG WALKS ON THE BEACH**
validate :append_messages_to_all_failed_validations
def append_messages_to_all_failed_validations
self.errors.each do |attribute, error|
#**YOU SHOULDNT BE DOING THIS LOL**
self.errors[attribute.to_sym] = "#{error} plus some"
end
end

Rails 3 - get full error message for one field

I have user.errors which gives all errors in my controller. So, i have the field :user_login which has its error(s). How can i get full error messages from user.errors ONLY for that field?
I can get just text of this field like that:
user.errors[:user_login] # Gives that 'can't be empty'
But i really want to do something like that
user.errors.get_full_message_for_field[:user_login] # 'Your login can't be empty'
Well, I know this question was explicitly posted for Rails 3.x, one and a half years ago, but now Rails 4.x seems to have the very method you were wishing, full_messages_for.
user.errors.full_messages_for(:user_login) #=> return an array
# if you want the first message of all the errors a specific attribute gets,
user.errors.full_messages_for(:user_login).first
# or
user.errors.full_messages_for(:user_login)[0]
It's less verbose than the previously used user.errors.full_message(:user_login, user.errors[:user_login].first).
Have a look at full_message here:
http://api.rubyonrails.org/classes/ActiveModel/Errors.html#method-i-full_message
A bit verbose but you may be able to do something like:
user.errors.full_message(:user_login, user.errors[:user_login])
We can get the error message of particular field by using
<%= resource.errors.full_messages_for(:email).join("") %>
output : Email cant be blank
If you want to check the particular field has error or not then check it by using
resource.errors.include?(:email)
output : true/false
Here is the code snippet for displaying only the first error for each field.
<!-- Display only first error for each field --->
<% entity.attributes.keys.each do |key| %>
<% if entity.errors.full_messages_for(key.to_sym).length > 0 %>
<li><%= entity.errors.full_messages_for(key.to_sym).first %></li>
<% end %>
<% end %>

Change error validation message in Paperclip

When you set a validation message in paperclip, such as
validates_attachment_presence, :image, :message => 'xxxx'
The custom message comes automatically prefixed with the name of the field, even though it has been overwritten with the :message . How do you totally override the message and make it totally custom?
Edit: typo
Not a real solution but a Easy one is to skip paperclip validation and write custom one.
validate :check_content_type
def check_content_type
if !['image/jpeg', 'image/gif','image/png'].include?(self.image_content_type)
errors.add_to_base("Image '#{self.image_file_name}' is not a valid image type") # or errors.add
end
end
I hope it can help
You actually want to do this inside your view rather than your model and it's actually quite straight forward. We're just going to loop through the errors, and when the one for your attachment comes up we'll ignore the field name:
<ul>
<% #myObject.errors.keys.each do |field| %>
<% #myObject.errors[field].each do |msg| %>
<% if field == :image_file_name %>
<li><%= msg %></li>
<% else %>
<li><%= field.to_s + " " + msg %></li>
<% end %>
<% end %>
<% end %>
</ul>
Replacing #myObject with the name of your model that should display only the message set to your attachment validation errors. This is just a simple example that displays them inline with the rest, but of course you could do anything you like with the messages. It's important to keep the name of the field that had the error in case you want to program any logic thats specific to its failure without having to rely on the error message staying exactly the same forever.
It's standard Rails behavior to show include the attribute name before the validation errors. You have a few options to work around this behavior:
Make your error message OK to have the attribute name prepended :)
Use a different error message formatter. It's pretty easy to write your own helper to iterate through an #object.errors and wrap messages in HTML tags. I prefer to use the error messages in-line near the fields so we always skip the attribute name.
Custom validation which adds the errors to base. This is easy, but wrong, since you're suggesting there's a validation error on a field. Still may solve your problem.
Override humanized_attribute_name for that attribute to hide it. humanized_attribute_name is probably used elsewhere, so this may cause other issues.
.
HumanizedAttributesOverride = {
:image => ""
}
def self.human_attribute_name(attr)
HumanizedAttributesOverride[attr.to_sym] || super
end
I don't know if it's just a typo inside your question, but it should be:
validates_attachment_presence :image, :message => 'xxxx'
And I would not use :message to add a custom error message, but put it inside a locales file.

How to display descriptive error message?

I have a problem in displaying the error message in Ruby on Rails. I am using:
rescue => Exception ex
#display ex.message
The output I get when I tried to display it in an alert messagebox is this:
"DBI::DatabaseError: 37000 (50000)
[Microsoft][ODBC SQL Server
Driver][SQL Server]Cannot approve
records for the specified date..: Exec
uspTestProc 279, 167, 2."
It displays some words that are not friendly to users. What I want is to display only these words: "Cannot approve records for the specified date"
Common practice in Rails is to use the "flash" session variable within the Controller:
# error catching logic goes here
flash[:error] = "There was an error!"
# notice logic goes here
flash[:notice] = "I am sending you a notice."
Then display it (possibly within a catchall layout):
<% if flash[:error] %>
<div id="error"><%= flash[:error] %></div>
<% end %>
<% if flash[:notice] %>
<div id="notice"><%= flash[:notice] %></div>
<% end %>
Was that what you are looking for?
I think an error like that can be catch by rescue_from
class ApplicationController
rescue_from MyException do
render :text => 'We have some issue in our database'
end
end
In any language, I would usually always handle the exceptions and show the user a dumbed down version.
Users shouldn't get to see the inner workings of something and exceptions are a great way to show them a big mess of nonsense.
I:
Log the actual exception because I, or the system maintainer needs to know exactly what happened, with a tracelog if possible.
Show the user either a tailored exception for specific to the problem - "You've entered the wrong data!"
Or a generic error - "Oh noes! something went hideously wrong!!1" - if it wasn't caused by the user or I haven't got a case for handling it (yet).

Flash[:notice] doesn't show properly for automatic validation

I'm using Rails 2.3.4/Ruby 1.9.1 for my application. In the view I have this to show error messages:
<%= content_tag('div', flash[:notice], :class => 'flash notice') if flash[:notice] %>
it works fine if I assign it manually from the controller such as:
flash[:notice] = "User Name can only contain letters, number - or _"
But for the automatic validation in the model such as:
validates_uniqueness_of :user_name
the error messages don't show! although the form doesn't submit which what should happen but I don't see the error messages.
Any ideas?
Thanks,
Tam
Unless this has changed very recently in rails, flash[:notice] is never populated by model validations. To display errors from a validation in the view, you would use the error_messages_for method.

Resources