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