为无效日期提升ActiveRecord :: RecordNotFound(或任何404状态)

Jam*_*rce 11 ruby-on-rails

在我的控制器控制器中,我Date.new用来创建一个在ActiveRecord中传递的日期对象.

end_range = Date.new(params[:year].to_i, params[:month].to_i, params[:day].to_i).end_of_day.to_formatted_s(:db)
Run Code Online (Sandbox Code Playgroud)

上面的问题是,如果用户试图手动更改URL中的参数,例如输入40日期参数,则Date.new失败(如预期的那样).但是,如果用户键入类似的内容,我宁愿不会出现500错误,而是404错误(因为你实际上永远不会有一天的记录40).

我尝试了各种条件(ifunless语句),raise ActiveRecord::RecordNotFound如果失败,但它在运行条件之前返回500错误(因此永远不会返回404).

有没有人知道更好的方法来处理它,或者是一种允许Date.new更优雅地失败以便条件语句可以运行的方法?

tad*_*man 30

在这种情况下,如果您想要将未处理的异常重新映射到以下类型的异常,您可以挽救一个异常并引发另一个异常:

def show
  begin
    end_range = Date.new(...)
  rescue ArgumentError
    # Invalid date
    raise ActiveRecord::RecordNotFound
  end
rescue ActiveRecord::RecordNotFound
  render(:partial => 'not_found', :layout => 'application', :status => :not_found)
end
Run Code Online (Sandbox Code Playgroud)

然而,简单地渲染和失败可能更有效.

def show
  begin
    end_range = Date.new(...)
  rescue ArgumentError
    return render(:partial => 'date_not_found', :layout => 'application', :status => :not_found)
  end
end
Run Code Online (Sandbox Code Playgroud)

您还可以使用rescue_fromApplicationController 的方法在更广泛的意义上执行此操作:

class ApplicationController < ActionController::Base
  rescue_from 'ArgumentError do
    render(:partial => 'exceptions/argument_error', :layout => 'application', :status => :not_found)
  end
end
Run Code Online (Sandbox Code Playgroud)