我有一个用户控制器,如果我愿意,我可以解决错误,如果没有找到用户,并将它们重定向到适当的页面。但我只想在某些路由而不是所有路由上使用rescue_from
方法。所以,几乎与
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found, except: [:new, :edit]
有办法做到这一点吗?感谢帮助!
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
答案 0 :(得分:1)
让我们首先只在需要时调用回调:
before_action :get_user, only: [:show, :edit, :update, :destroy]
但是,查询的记录甚至没有分配给变量,因此可以在以后使用。让我们解决一下:
class UserController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# ...
private
def set_user
@user = User.find(params[:id])
end
end
虽然我们可以使用rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
- 我们甚至不知道实际上是对失败用户的查询!例如,它可能是ApplicationController
中上游定义的其他一些回调。
此外,当无法找到资源时,您的应用程序应通过发送404 - NOT FOUND
或410 - GONE
响应来告知客户端。不是通过重定向,因为它发送一个3xx响应代码,表明资源已暂时移动。
您可以直接在回调中解救异常:
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
虽然在大多数情况下最好将其保留为默认处理程序,而不是捏破应用程序的REST界面并添加一堆复杂性。
答案 1 :(得分:0)
- 更新 -
可能将其放入
private
def problem
begin
@user = User.find(params[:id])
rescue ActiveRecord::RecordNotFound
redirect_to user_path, error: "Sorry, no user found."
end
end
并有一个before_action
before_action :problem, except: [:new, :edit]
答案 2 :(得分:0)
解决方案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
解决方案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
答案 3 :(得分:0)
我看到了最明显的两种变体来解决通过操作名称过滤器呈现错误的问题:
rescue_from Exception, with: ->(e) { %w(new edit).include?(action_name) && method(:record_not_found)[e] }
或
rescue_from Exception do |e|
%w(new edit).include?(action_name) && method(:record_not_found)[e]
end