14

I'm using devise and I put the login and sign up forms in the same page, now when I write invalid login details or don't fill required input data at the sign up form.

I'm redirecting to the /users page if I'm trying to register or to the /users/sign_in if I try to login with the errors i made...

I want to stay in the same page and show the errors in the same page.

how can I do it?

thanks you very much, I need a quick help :)

rohin-arka
  • 779
  • 4
  • 10
gal
  • 929
  • 4
  • 21
  • 39

5 Answers5

18

I found the solution to this problem on StackOverFlow some time ago. Here's what worked for me

# In application.html.erb
<% flash.each do |name, msg| %>

  # New code (allow for flash elements to be arrays)
  <% if msg.class == Array %>
    <% msg.each do |message| %>
      <%= content_tag :div, message, :id => "flash_#{name}" %>
    <% end %>
  <% else %>

    # old code
    <%= content_tag :div, msg, :id => "flash_#{name}" %>

  <% end %> #don't forget the extra end
<% end %>

and

# Wherever you want Devise's error messages to be handled like 
# your other error messages
# (in my case, registrations_controller.rb, a custom controller)
flash[:notice] = flash[:notice].to_a.concat resource.errors.full_messages

See original post here

...and think about accepting answer, 50% is a bit low! ;)

===== EDIT =====

If you need to redirect to another page when errors occurs, you'll have to override controllers (check Devise Wiki or search stackoverflow for howto) but it should look like something like that

# CUSTOM DEVISE CONTROLLER
class RegistrationsController < Devise::RegistrationsController

  # POST /resource
  def create
    build_resource

    if resource.save
      if resource.active_for_authentication?     
        set_flash_message :notice, :signed_up if is_navigational_format?
        sign_in(resource_name, resource)
        respond_with resource, :location => redirect_location(resource_name, resource)
      else
        set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message.to_s if is_navigational_format?
        expire_session_data_after_sign_in!
        respond_with resource, :location => after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords(resource)
      # Solution for displaying Devise errors on the homepage found on:
      # https://stackoverflow.com/questions/4101641/rails-devise-handling-devise-error-messages
      flash[:notice] = flash[:notice].to_a.concat resource.errors.full_messages
      redirect_to root_path # HERE IS THE PATH YOU WANT TO CHANGE
    end
  end
end
Community
  • 1
  • 1
Lucas
  • 2,886
  • 1
  • 27
  • 40
  • don't working... when i click on login or register i'm stil redirecting to anthoer page and there i'm getting the errors... – gal Jul 12 '11 at 09:31
  • You have to override your controllers and changes the response route. See my edit. – Lucas Jul 12 '11 at 09:39
  • you forget to tell me to put in the routes: :registrations => "registrations" – gal Jul 12 '11 at 10:06
10
Just add this code under devise->sessions->new.html.erb(View part)
  <%= devise_error_messages! %>
    <% flash.each do |key, value| %>
       <div class="flash <%= key %>"><%= value %></div>
    <% end %>
5

After a lot of searching, I found that the following worked pretty well for my purposes. Just create the Devise Helper and store the resource.errors.full_messages in a flash error container.

Specifically:

module DeviseHelper

  def devise_error_messages!
     flash[:error] = resource.errors.full_messages.first
  end
end
Naysawn
  • 221
  • 3
  • 4
3

just a little thing to add:

Do not print the entire flash hash, print only specific keys. In some circumstances, Devise adds a :timedout key to the flash hash, which is not meant for display. Remove this key from the hash if you intend to print the entire hash.

NoDisplayName
  • 15,246
  • 12
  • 62
  • 98
0

Over riding your devise controllers may help or work when you try to test that on your local but it won't work when you deploy your code. And over riding the gems controller is also a bad practice. So, best way to do it, is to make a new controller, in controllers 'registrations_controller.rb'. and in that controller. " Class RegistrationsControlller < Devise::RegistrationsController " And over ride the methods in that controller.

Sushant
  • 377
  • 4
  • 8