Home > Mobile >  Render and/or redirect Ruby
Render and/or redirect Ruby

Time:01-30

i have login page with 2 sessions client and admin so when client logged in i do redirect to complete the form and when admin logged in i redirect him to dashboard, the problem is :

ActionController::DoubleRenderError (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".)

  def login
    @institute = Configuration.find_by_config_key("LogoName")
    available_login_authes = FedenaPlugin::AVAILABLE_MODULES.select{|m| m[:name].classify.constantize.respond_to?("login_hook")}
    selected_login_hook = available_login_authes.first if available_login_authes.count>=1
    if selected_login_hook
      authenticated_user = selected_login_hook[:name].classify.constantize.send("login_hook",self)
    else
      if request.post? and params[:user]
        @user = User.new(params[:user])
        user = User.find_by_username @user.username
        if user.present? and User.authenticate?(@user.username, @user.password)
          authenticated_user = user 
        end
      end
    end
    if authenticated_user.present?
      successful_user_login(authenticated_user) and return
    elsif authenticated_user.blank? and request.post?
      flash[:notice] = "#{t('login_error_message')}"
    end
  end

  private
  def successful_user_login(user)
    session[:user_id] = user.id
    flash[:notice] = "#{t('welcome')}, #{user.first_name} #{user.last_name}!"
    redirect_to session[:back_url] || {:controller => 'user', :action => 'dashboard'}
    if user.client
      redirect_to session[:back_url] || {:controller => 'client', :action => 'complete_registration'}
    end
  end
end

CodePudding user response:

You said right redirect_to is not a return method, the codes above is executed too. In you successful_user_login if user is client, you are calling redirect_to twice, so you can refactor this method to:

if user.client
  redirect_to session[:back_url] || {:controller => 'client', :action => 'complete_registration'}
else
  redirect_to session[:back_url] || {:controller => 'user', :action => 'dashboard'}
end

CodePudding user response:

ActionController::DoubleRenderError is a error thrown by Ruby on Rails when a controller action tries to render or redirect a response twice. In your code, the action attempts to redirect the user to both 'user/dashboard' and 'client/complete_registration' depending on the user's status as a client. This will result in a DoubleRenderError. Notice that rendering or redirecting do not returns from the method.

Here are some untested code examples with different approaches:

You can calculate the controller and the action before calling redirect_to:

def successful_user_login(user)
  session[:user_id] = user.id
  flash[:notice] = "#{t('welcome')}, #{user.first_name} #{user.last_name}!"

  controller, action = if user.client
    ["client", "complete_registration"]
  else
    ["user", "dashboard"]
  end

  redirect_to session[:back_url] || {controller: controller, action: action}
end

You can also do an if and return after first redirect_to:

  def successful_user_login(user)
  session[:user_id] = user.id
  flash[:notice] = "#{t('welcome')}, #{user.first_name} #{user.last_name}!"

  if user.client
    redirect_to session[:back_url] || {:controller => 'client', :action => 'complete_registration'}
    return
  end

  redirect_to session[:back_url] || {:controller => 'user', :action => 'dashboard'}
end

Or do an if else:

def successful_user_login(user)
  session[:user_id] = user.id
  flash[:notice] = "#{t('welcome')}, #{user.first_name} #{user.last_name}!"

  if user.client
    redirect_to session[:back_url] || {:controller => 'client', :action => 'complete_registration'}
  else
    redirect_to session[:back_url] || {:controller => 'user', :action => 'dashboard'}
  end
end
  • Related