【问题标题】:AbstractController::DoubleRenderError Error and using redirect_toAbstractController::DoubleRenderError 错误和使用redirect_to
【发布时间】:2014-03-22 23:04:40
【问题描述】:

我有一个更新方法,它使用具有自己的渲染调用的保存和删除方法。下面是代码:

更新方法:

def update_book
  self.delete_book
  params[:Name] = params[:NewName]
  self.save_book
end

删除方法:

def delete_book
 # Do something
 rescue BookDoesNotExist => exception
    render status: 404
    return
 end
 head 200
end

保存方法:

def save_book
 # Do something
 rescue BookDoesNotExist => exception
    render status: 404
    return
 end
 rescue BookAlreadyExist => exception
    render status: 409
    return
 end
 head 200
end

当我使用一些输入运行此程序时,系统会抛出“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

我理解这是因为在删除和保存方法中都使用我传递的输入引发异常。我该如何处理这种情况?

做了一些研究,我了解到我需要使用重定向。所以我明白当我的删除方法抛出异常/渲染时,我应该返回并且不应该调用保存方法。

这是我尝试使用 redirect_to 的方法:

更新方法:

def update_book
  redirect_to action: self.delete_book and return if status=404 end
  params[:Name] = params[:NewName]
  self.save_book
end

我做得对还是有其他最好的方法来处理重定向?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    当您的 delete_booksave_book 方法收到异常时,它们会渲染某些内容然后返回,这是正确的。

    但是return 会将执行返回给调用者方法,即update_book。此调用方方法不知道发生的异常,因此将完成其工作并呈现它必须呈现的内容。

    要修复,您的 delete_booksave_book 方法需要向调用者返回成功状态,如下所示:

    def delete_book
      # ... Do something
    
      rescue BookDoesNotExist => exception
        render status: 404
        return false
      end
    
      head 200
      true
    end
    

    然后你的调用方法应该检查这个状态:

    def update_book
      return unless self.delete_book
      params[:Name] = params[:NewName]
      return unless self.save_book
    end
    

    另一种方法是使用控制器的rescue_from

    在你的ApplicationController

    class ApplicationController < ActionController::Base
      rescue_from BookDoesNotExist, with: :redirect_book_not_existing
    
      private 
    
      def redirect_book_not_existing
        render status: 404
      end
    end
    

    从现在开始,每当您的控制器收到BookDoesNotExist 异常时,执行将停止并执行render status: 404 行。当然你不能rescue其他方法中的异常,像这样:

    def delete_book
     # Do something
    
     head 200
    end
    

    你的代码会更干净

    【讨论】:

      猜你喜欢
      • 2020-03-28
      • 2015-11-27
      • 1970-01-01
      • 2014-07-02
      • 2012-01-26
      • 1970-01-01
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多