在RubyonRails中处理无ID错误的最佳方法是什么



在我的控制器中,我经常使用这样的东西来验证project是否真的属于给定的user:

private
def authorized_user
  @project = Project.find(params[:id])
  redirect_to root_path unless current_user?(@project.user)
end

这很好,因为用户A看不到用户B的项目(他被转发到根页面)。

然而,只有当请求了真正存在的project URL时,这才有效。

例如,URL http://localhost:3000/projects/1将显示用户的项目,或者转发到根URL(如果另一个用户试图访问该项目)。

但当我试图访问数据库中根本不存在的项目时,,例如:

http://localhost:3000/projects/777

我得到一个丑陋的ActiveRecord::RecordNotFound错误:

Couldn't find Person with id=777

改善用户体验的最佳方式是什么?

我还从来没有部署过Rails项目,所以我甚至不知道在生产模式下这个错误会是什么样子。

有人能帮忙吗?

谢谢。。。

我个人喜欢使用这个:

@project = Project.where(id: params[:id]).first

若项目不存在,@project将为零。

尝试:

class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, :with => :render_404
  # Render 404 page when record not found
    def render_404      
       render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
    end
end

首先,为了避免未经授权的用户访问项目,您应该确定查找方法的范围:

current_user.projects.find(params[:id])

通过这种方式,您将在开发中得到"找不到id为的项目"的错误。为了避免这种情况,您可以使用:

current_user.projects.find_by_id(params[:id])

它返回nil而不是exception,但有充分的理由说明您通常不应该这样做。在一个写得很好的rails应用程序中,任何用户访问不应该访问的项目的唯一时间是手动更改url中的id。您希望在日志中报告这一点,而不是悄悄跳过。

最后,要抛出403 Forbidden而不是404 Not Found,您可以考虑使用许多授权宝石中的一个(脑海中浮现出Ryan Bates的cancan)。

编辑:哦,在生产中,ActiveRecord::RecordNotFound将呈现404.html页面,也就是说,这些不是你想要的项目。

根据您想要处理它的方式,您可以使用

@project = Project.find_by_id(params[:id])

如果没有找到记录,这将使@project为nil,并且您将不得不手动处理该情况。

另一个解决方案是抛出404,这是有意义的,因为资源不在那里。您可以在任何控制器(或应用程序控制器)中使用轻松完成此操作

rescue_from ActiveRecord::RecordNotFound, :with => :not_found
def not_found
  raise ActionController::RoutingError.new('Not Found')
end

这将导致类似于:

class ApplicationController < ..
  rescue_from ActiveRecord::RecordNotFound, :with => :not_found
  def not_found
    raise ActionController::RoutingError.new('Not Found')
  end
end

后一种解决方案将向用户显示默认的404(未找到)错误页面。在第一种情况下,你有更多的控制权,但代价是在任何地方都这样做

希望能有所帮助。

相关内容

  • 没有找到相关文章

最新更新