简体   繁体   English

在特定路线上使用rescue_from 的Rails

[英]Rails using rescue_from on specific routes

I have a user controller that, if I want to, I can rescue the error if no user is found and redirect them to the appropriate page.我有一个用户控制器,如果我愿意,如果没有找到用户,我可以挽救错误并将它们重定向到适当的页面。 But I would like to only use the rescue_from method only on certain routes instead of all the routes.但我想只在某些路线上而不是所有路线上使用rescue_from方法。 So, pretty much something similar to所以,几乎类似于

rescue_from ActiveRecord::RecordNotFound, with: :record_not_found, except: [:new, :edit]

Is there a way to do this?有没有办法做到这一点? Help is appreciated!帮助表示赞赏!

class UserController < ApplicationController

  before_action :get_user

  rescue_from ActiveRecord::RecordNotFound, with: :record_not_found

  def show
  end

  def new
  end

  def create
  end

  def edit
  end

  def update
  end

  private
    def get_user
      User.find(params[:id])
    end

    def record_not_found
      redirect_to user_path, error: "Sorry, no user found."
    end 
end

--UPDATE -- - 更新 -

Possibly put it into可能放进去

private

def problem
  begin
    @user = User.find(params[:id])
  rescue ActiveRecord::RecordNotFound
    redirect_to user_path, error: "Sorry, no user found."
  end
end

and have a before_action并有一个 before_action

before_action :problem, except: [:new, :edit]

This question might also help rescue from ActiveRecord::RecordNotFound in Rails这个问题也可能有助于从 Rails 中的 ActiveRecord::RecordNotFound 中拯救出来

Lets start by only calling the callback when its needed:让我们从只在需要时调用回调开始:

before_action :get_user, only: [:show, :edit, :update, :destroy]

However the queried record is not even being assigned to a variable so it can be used later.然而,查询的记录甚至没有被分配给一个变量,所以它可以在以后使用。 Lets fix that:让我们解决这个问题:

class UserController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]

  # ...

  private 

    def set_user
       @user = User.find(params[:id])
    end
end

While we could use rescue_from ActiveRecord::RecordNotFound, with: :record_not_found - We don't even know that it was actually the query for a user that failed!虽然我们可以使用rescue_from ActiveRecord::RecordNotFound, with: :record_not_found - 我们甚至不知道它实际上是对用户的查询失败了! It could be some other callback defined upstream in ApplicationController for example.例如,它可能是在ApplicationController上游定义的一些其他回调。

Also when a resource cannot be found your application should be telling the client that by sending a 404 - NOT FOUND or 410 - GONE response.此外,当找不到资源时,您的应用程序应该通过发送404 - NOT FOUND410 - GONE响应来告诉客户端。 Not by redirecting as that sends a 3xx response code which indicate that a resource has moved temporarily.不是通过重定向,因为它会发送 3xx 响应代码,指示资源已临时移动。

You could rescue the exception directly in the callback instead:您可以直接在回调中拯救异常:

    def set_user
       begin 
         @user = User.find(params[:id])
       rescue ActiveRecord::RecordNotFound
         @users = User.all
         flash.now[:error] = "User not found"
         # note that we render - not redirect!
         render :index, status: 404
       end
    end

Although in most cases it is better to leave it to default handler rather than bungle up the REST interface of your app and add a bunch of complexity.尽管在大多数情况下,最好将它留给默认处理程序,而不是搞砸应用程序的 REST 接口并增加一堆复杂性。

Solution A, use a common parent controller that define this before_filter, like:解决方案 A,使用定义此 before_filter 的公共父控制器,例如:

class RescueNotRoundRecordController < ApplicationController
  rescue_from ActiveRecord::RecordNotFound, with: :record_not_found

  private
  def record_not_found
    redirect_to user_path, error: "Sorry, no user found."
  end 
end

class UserController < RescueNotRoundRecordController
  before_action :get_user
end

Solution B, use module to do that, which I think is the better way to go:解决方案 B,使用模块来做到这一点,我认为这是更好的方法:

module RescueNotRoundRecord
  def self.included(mod)
    mod.class_eval do
      rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
    end
  end

  private
  def record_not_found
    redirect_to user_path, error: "Sorry, no user found."
  end 
end

class UserController < ApplicationController
  include RescueNotRoundRecord
end

I'm seeing the most obvious two variants to solve problem of rendering the error with a filter by action name:我看到了最明显的两种变体来解决通过操作名称过滤器呈现错误的问题:

rescue_from Exception, with: ->(e) { %w(new edit).include?(action_name) && method(:record_not_found)[e] }

or或者

rescue_from Exception do |e|
   %w(new edit).include?(action_name) && method(:record_not_found)[e]
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM