Ruby-on-rails Rails:DoubleRenderError - “在此操作中多次调用渲染和/或重定向”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14670585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:22:17  来源:igfitidea点击:

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

ruby-on-railsredirectdevisesuperinternal-server-error

提问by Alon Shmiel

I want to redirect by the role_idsof the user:

我想由role_ids用户重定向:

  • If it's equal to 2, redirect to workers_path.
  • if it's equal to 1, redirect to tasksadmins_path.
  • 如果它等于 2,则重定向到workers_path.
  • 如果它等于 1,则重定向到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"=>"[email protected]",
 "password"=>"[FILTERED]",
 "remember_me"=>"0"},
 "commit"=>"Sign in"}

This is my user_session_controller.rb:

这是我的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:

这是我的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

采纳答案by Alon Shmiel

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

回答by Mikhail Nikalyukin

You shouldn't return redirect_toin the after_sign_in_path_for. You should return url:

你不应该redirect_toafter_sign_in_path_for. 你应该返回网址:

  def after_sign_in_path_for(user)
     if current_user.role_ids == [2]
       return workers_url
     else
       return tasksadmins_url
     end
  end

回答by Promise Preston

I faced this issue while using devisegem for my admin account management, but mine was on a production server.

我在使用devisegem 进行管理员帐户管理时遇到了这个问题,但我的是在生产服务器上。

AbstractController::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".):

AbstractController::DoubleRenderError (在这个动作中多次调用渲染和/或重定向。请注意,你只能调用渲染或重定向,并且每个动作最多只能调用一次。还要注意,重定向和渲染都不会终止动作的执行,所以如果要在重定向后退出操作,则需要执行类似“redirect_to(...) 并返回”之类的操作。):

The issue was that I wanted to sign_in into the admin dashboard, rather than entering the admin_dashboardURL into the browser, I put in the admin_sign_inURL in the browser, meanwhile, an admin account was already logged in. So when I tried to sign in it didn't work, because I can't sign-in 2 accounts at the same time to the admin dashboard.

问题是,我想sign_in到管理仪表板,而不是进入admin_dashboard网址到浏览器中,我把在admin_sign_in在浏览器的网址,同时,管理员帐户已经登录。所以,当我试图登录它不起作用,因为我无法同时将 2 个帐户登录到管理仪表板。

Here's how I solved it:

这是我解决它的方法:

  1. Enter the URL for the admin dashboard into the browser, which signed me into the previous account
  2. Log out from the account on the admin dashboard
  3. And then sign-in to the admin dashboard using the account that I want.
  1. 在浏览器中输入管理仪表板的 URL,这使我登录到以前的帐户
  2. 从管理仪表板上的帐户注销
  3. 然后使用我想要的帐户登录管理仪表板。

That's all.

就这样。

I hope this helps

我希望这有帮助