如何在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}.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: ""