Reputation: 643
I have a form to create product. A product has many fields with validations. For example:
Say user tried to save empty form. Now I want to show have following kind of error hash:
{
general: 'Something went wrong, Please contact support team.'
product: {
name: 'Name can not be blank',
description: 'Description can not be blank'
}
}
So that I can show general
error on top(if any) or I will be able to show error just above the corresponding field.
In products_controller
,
def create
@product = Product.new(product_params) # Strong params
if @product.save
flash[:success] = "Welcome to the Sample App!"
redirect_to @product
else
render 'new'
end
end
How do I show error corresponding to each field? I'm aware of the @product.errors
will give me errors. But I want to keep a general
error key as well. flash
are one way to do it. But as far as I know, we can send only text message in a flash. What should be the right way to it in Rails?
Thanks,
Upvotes: 0
Views: 1573
Reputation: 1549
Simply you can use <%=f.error_span(:name) %>
in your html.erb file
Example:
<div class="form-group">
<%= f.label(:name) %>
<%= f.text_field(:name) %>
<%=f.error_span(:name) %>
</div>
Note: You need twitter-bootstrap-rails gem for this to work and it will make validations easy for all the pages. Let me know if this is what you needed!!
Upvotes: 0
Reputation: 4940
Here is my solution for this problem. I've created a simple helper method that I use in the view per field. It's pretty extendable as well, so don't feel limited by it's current state. It can easily accept additional arguments/options to be able to add custom CSS classes, etc.
# app/helpers/form_errors_helper.rb
module FormErrorsHelper
def error_message_on(object, method)
return unless object.respond_to?(:errors) && object.errors.include?(method)
errors = field_errors(object, method).join(', ')
content_tag(:div, errors, class: 'form-group-error')
end
private
def field_errors(object, method)
object.errors[method]
end
end
# css
.form-group-error {
# your styling here
}
# form
<%= form_for(@product) do |f| %>
<div class="form-group">
<%= f.label(:name) %>
<%= f.text_field(:name) %>
<%= error_message_on(f.object, :name) %>
</div>
<div class="form-group">
<%= f.label(:description) %>
<%= f.text_area(:description) %>
<%= error_message_on(f.object, :description) %>
</div>
<% end %>
With this, you can add another key, general
to the messages hash.
Let's say you do that in your model.
errors.add(:general, 'This is my general error')
Then, in your view, you just use the same helper.
error_message_on(f.object, :general)
If you need different styling for the "general" error, you can pass in additional arguments to that helper, like additional CSS classes.
Upvotes: 1