Search code examples
ruby-on-railshttp-redirectdevisesuperinternal-server-error

Rails: DoubleRenderError - "Render and/or redirect were called multiple times in this action"


I want to redirect by the role_ids of the user:

  • If it's equal to 2, redirect to workers_path.
  • if it's equal to 1, redirect to tasksadmins_path.

I defined the next things:

class ApplicationController < ActionController::Base
  include ApplicationHelper

  protect_from_forgery
  before_filter :authenticate_user!

  def stored_location_for(user)
    nil
  end

  def after_sign_in_path_for(user)
     if current_user.role_ids == [2]
       return redirect_to(workers_path)
     else
       return redirect_to (tasksadmins_path)
     end
  end
end

but when I sign in, I got errors:

AbstractController::DoubleRenderError in UserSessionsController#create

Render and/or redirect were called multiple times in this action. Please note 
that you may only call render OR redirect, and at most once per action. Also 
note that neither redirect nor render terminate execution of the action, so 
if you want to exit an action after redirecting, you need to do something 
like "redirect_to(...) and return".
Rails.root: /home/alon/alon/todolist

Application Trace | Framework Trace | Full Trace
app/controllers/user_sessions_controller.rb:5:in `create'
Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"jRNZkIXvToEhl9YVxaQoa2hLJiSaHI6JAdfpUNAQMJI=",
 "user"=>{"email"=>"worker216@gmail.com",
 "password"=>"[FILTERED]",
 "remember_me"=>"0"},
 "commit"=>"Sign in"}

This is my user_session_controller.rb:

class UserSessionsController < Devise::SessionsController
  include ApplicationHelper

  def create
      response = super

      require "uri"
      require "net/http"

      ## get the user id from the database
      user_id = session['warden.user.user.key'][1][0];

      ## get the row by id
      user = User.find(user_id)

      # ============================
      # Ensure that a user exists
      # ============================

      code, body = http_request(Net::HTTP::Put.new("/api/v1/users/external/#{user_id}"), email: user.email);
      if code != 200
         Rails.logger.error("Unable to register user #{current_user.email} at Licensario");
      end

      response
   end
end

and this is my routes.rb:

TODOLIST::Application.routes.draw do

    devise_for :users, :controllers => { :sessions => 'user_sessions'} do
        get '/users/sign_out' => 'devise/sessions#destroy'
    end

    resources :tasksadmins
    resources :workers
    root to: "workers#index"
end

Solution

  • I added to 'create' the next lines:

    in the beginning, I wrote:

    resource = warden.authenticate!(:scope => resource_name)
    

    and then I wrote in the end of the 'create' function:

    sign_in(resource_name, resource)
    
    if current_user.role_ids == [2]
       respond_with resource, :location => workers_path
    else
       respond_with resource, :location => tasksadmins_path
    end
    

    so my create looks so:

    class UserSessionsController < Devise::SessionsController
        include ApplicationHelper
    
        def create
    
            resource = warden.authenticate!(:scope => resource_name)
    
            require "uri"
            require "net/http"
    
            ## get the user id from the database
            user_id = session['warden.user.user.key'][1][0];
    
            ## get the row by id
            user = User.find(user_id)
    
            # ============================
            # Ensure that a user exists
            # ============================
    
            code, body = http_request(Net::HTTP::Put.new("/api/v1/users/external/#{user_id}"), email: user.email);
            if code != 200
               Rails.logger.error("Unable to register user #{current_user.email} at Licensario");
            end
    
            sign_in(resource_name, resource)
    
            if current_user.role_ids == [2]
               respond_with resource, :location => workers_path
           else
               respond_with resource, :location => tasksadmins_path
           end
    
        end
    end