I want to intercept the validation errors thrown by Rails on a registration form. In English this works like this:
if @user.save
# Do whatever...
else
@errors = @user.errors.full_messages
if [email protected]("Email has already been taken").nil?
# Present the user with a 'forgot password' UI
else
# Display the error on the screen
end
end
Since the test for a particular error is based on a hard-coded string comparison, it's a bit tenuous but it works when I only have a handful of exception cases.
However this becomes impossibly unwieldy when using more than one language, as the validation errors have already been localized and I'd have to use something monstrous like this:
if [email protected]("Email has already been taken").nil? ||
[email protected]("Email n'est pas disponible").nil? ||
[email protected]("Email wurde bereits angenommen").nil? || ...
I'd like to think that Rails could give me a status code (like HTTP does) so I don't need to compare strings, but I haven't seen that documented anywhere.
What's the best workaround?
You should be able to get a few more details by interrogating @user.errors.details
. It gets a brief mention in the guide to validations.
Essentially you should see something like this when the email is taken:
> user.errors.details
=> { :email => [{:error => :taken, :value => '[email protected]'}] }
That would allow your check for a "taken" email to be:
if @errors.details[:email] &&
@errors.details[:email].any? { |error| error[:error] == :taken }