In my app, I sometimes create a User on the fly, and a user's email must be a valid format, and be unique.
I would like to redirect to different places depending on WHICH validation caused the error to be raised: invalid format vs duplicate.
In my code I have
begin
user.save!
flash[:notice] = "Created new user #{email} with password #{password}"
rescue ActiveRecord::RecordInvalid => e
flash[:alert] = "Failed to create account because #{e.message}"
redirect_to SOMEPLACE
end
If the email is invalid format (such as "user@example") e.message is "Validation failed: Email is invalid"
If the email already exists in the table, e.message is "Validation failed: Email has already been taken"
I hate the idea of parsing e.message text to determine the reason... is there a better way for a rescue handler to detect the underlying reason a ActiveRecord::RecordInvalid exception was thrown?
P.S. I know in THIS example I can simply check ahead for the email already existing before doing a save, but I'm trying to understand the general solution to detecting and acting on different validation failures throwing the same exception.
The standard Rails way to do this is not to use the bang operator, which raises an exception, but to use the standard save method and check whether it returned true or false:
if @user.save
flash[:notice] = "User created."
redirect_to :action => :index
else
flash[:alert] = "User could not be created."
render :action => :new
end
And in your user creation view:
<% if @user.errors.any? %>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With