Search code examples
authenticationruby-on-rails-4devisespreespree-auth-devise

Show validation errors in view for custom Devise login form


At the moment, I'm building a Rails platform using Spree Commerce where I need two Devise login forms.

The default Devise login forms are already implemented. For the second (custom) Devise form, I created the following view:

global_login.html.erb

<div class="inner">
  <h2 class="large-margin">
    Login
   </h2>
   <%= form_for(Spree::User.new, :url => spree_login_path) do |f| %>
     <%= f.error_messages %>
     <%= f.email_field :email, {:value => params[:email], :placeholder => 'Email address', :class => 'input'} %>
     <%= f.password_field :password, {:placeholder => 'Password', :class => 'input'} %>
     <%= f.submit 'Login', :class => 'submit' %>
  <% end %>
</div>

This view does display a Devise login form. However, every time I submit the form, I'm being redirected to the default Devise view where the validation errors are shown.

Does somebody know a solution to this problem?

Cheers!


Solution

  • I found a workaround for this issue. I added a param to one of the forms named "inside_cart". When the request is send to the #create method, I check if the param is present.

    I overwrote the Spree::UserSessionsController#create method as follows:

    Spree::UserSessionsController.class_eval do
      layout false
    
      def create
        authenticate_spree_user!
          if spree_user_signed_in?
            respond_to do |format|
              format.html {
                flash[:success] = Spree.t(:logged_in_succesfully)
                redirect_back_or_default(after_sign_in_path_for(spree_current_user))
              }
              format.js {
                user = resource.record
                render :json => {:ship_address => user.ship_address, :bill_address => user.bill_address}.to_json
              }
            end
          else
            if params[:spree_user] && params[:spree_user][:inside_cart]
              flash.now[:error] = t('devise.failure.invalid')
              render :new, layout: false
            else
              flash.now[:error] = t('devise.failure.invalid')
              render 'spree/users/global_login', layout: 'spree/layouts/spree_application'
            end
          end
        end
      end