在Ruby on Rails中处理没有ID错误的最佳方式是什么?
在我的控制器,我使用这样大量来验证project
真正属于给定user
:在Ruby on Rails中处理没有ID错误的最佳方式是什么?
private
def authorized_user
@project = Project.find(params[:id])
redirect_to root_path unless current_user?(@project.user)
end
这个伟大的工程,因为用户A不能看到用户B的项目(他被转发到而不是根页面)。
但是,只有project
网址被请求确实存在。
例如,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
将是零。
根据您要如何处理它,你可以使用
@project = Project.find_by_id(params[:id])
这将让@project是零,如果没有发现任何记录,你将必须手动处理的情况。
另一个解决方案是抛出一个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(NOT找到)错误页面。在第一种情况下,你有更多的控制权,但是以无所不在的代价
希望有帮助。
首先,以避免未经授权的用户访问项目,就请您范围查找方法:
current_user.projects.find(params[:id])
这样你会得到发展的错误“无法与ID找到项目”。为了避免这种情况,你可以使用:
current_user.projects.find_by_id(params[:id])
返回nil
,而不是例外,但有很好的理由,你通常不应该。在写得很好的rails应用程序中,任何用户访问项目的唯一时间是他不应该在手动更改url中的id时使用。您希望在日志中报告这种情况,而不是默默跳过。
最后,要抛出403 Forbidden而不是404 Not Found,你可以考虑使用许多授权宝石之一(Ryan Bates想到的cancan
)。
编辑:哦,在生产中,ActiveRecord :: RecordNotFound将渲染404.html页面,也就是这些不是你正在寻找的项目。
你在这里做的很好。非常感谢你的帮助!哇,有很多非常好的答案可以在这个线程中选择... – Tintin81 2013-02-15 10:55:15
只需要明确将响应重定向到404.html - 它们是很好的示例,如何更改默认行为,但在此不需要它们案件。正如我所说的,在生产中,Rails默认是这样做的。而在开发中,您希望获得例外页面,而不是404页面。 – Pandaamonium 2013-02-15 15:31:01
尝试:
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
谢谢你的帮助! – Tintin81 2013-02-15 10:52:05
好的,谢谢!在这种情况下,“first”究竟做了什么?我以为'第一'选择第一个记录...但是我是一个n00b ... – Tintin81 2013-02-14 19:47:41
好吧,为了补救你的无聊,请阅读本指南:[Query Interface](http://guides.rubyonrails.org/active_record_querying。 HTML)。你会在那里找到答案。 :) – 2013-02-14 19:51:21
好的,我明白了。它返回'nil'而不是抛出异常。但是我必须在下一行测试nil值,然后...... – Tintin81 2013-02-14 20:25:29