如何在rails控制器中处理ActiveRecord :: RecordNotFound?
我有一个用户和活动的应用程序。 每个用户都有几个事件。 当用户想要查看特定事件时,他将执行此操作:
def show begin @userEvents = current_user.event @event = @userEvents.find(params[:id]) rescue ActiveRecord::RecordNotFound redirect_to :controller => "main", :action => "index" end respond_to do |format| format.html # show.html.erb format.json { render json: @event } end end
如果没有为用户找到事件,则意味着他使用URL播放并且他试图获得的事件不属于他。 我想要将他重定向到主页面,或者只是显示页面,其中包含未找到事件的错误。 如果我尝试运行上面的代码,则会触发此错误:
AbstractController::DoubleRenderError in EventsController#show
解决这个问题的最佳方法是什么?
重定向后返回
begin @userEvents = current_user.event @event = @userEvents.find(params[:id]) rescue ActiveRecord::RecordNotFound redirect_to :controller => "main", :action => "index" return end
调用redirect_to
不会从您的action方法返回,这就是为什么转到respond_to
块会导致DoubleRenderError
。 解决这个问题的一种方法是:
redirect_to :controller => "main", :action => "index" and return
但是,更好的解决方案可能是以声明方式从此exception中解救,或者只是让它传播到客户端。 前者看起来像这样:
class YourController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, with: :dude_wheres_my_record def show # your original code without the begin and rescue end def dude_where_my_record # special handling here end end
如果您只是让exception更快,用户将在生产模式下看到public/404.html
页面。
在应用程序控制器中,请写:
rescue_from (ActiveRecord::RecordNotFound) { |exception| handle_exception(exception, 404) } protected def handle_exception(ex, status) render_error(ex, status) logger.error ex end def render_error(ex, status) @status_code = status respond_to do |format| format.html { render :template => "error", :status => status } format.all { render :nothing => true, :status => status } end end
创建一个页面error.html.erb
<%= t "errors.#{@status_code}.heading" %> <%= t "errors.#{@status_code}.subheading" %>
<%= t "errors.#{@status_code}.description" %>
<% if defined? root_path %> <%= link_to t(:return_to_home), root_path %> <% end %>
在en.yml
en: errors: "404": description: "The page you are looking for does not exist!" heading: "Record not found" subheading: ""