如果用户尝试提交表单或访问使用以下内容的服务:
Model.find(params[:id]) # if model does not exist, throw ActiveRecord::RecordNotFound
如果找不到实例,则抛出异常。然而,我很少看到人们在开始/救援块中包含该声明,即使您创建了一个脚手架,rails生成器也不会将开始/救援块中的查找调用包裹起来。
这是否有原因?
答案 0 :(得分:4)
我认为这是因为最常见的情况是,如果你按照id来追踪一个对象并且它不存在那么这就是例外。异常会冒出来,rails将把它作为404处理,这通常是合适的。
如果是对象可能存在或不存在的情况,那么捕获异常或使用Model.find_by_id(params[:id])
并检查nil对象都能很好地工作。
答案 1 :(得分:2)
一个原因可能是错误处理逻辑被传递给应用程序中的救援处理程序。
你的控制器:
def some_action
@foo = Foo.find!(params[:id])
# Exception will raise here ...
# ...
end
然后指定
rescue_from ActiveRecord::RecordNotFound, :some_method_that_will_render_a_404
(请参阅this获取解释)
脚手架只是在短时间内获得某些东西的快捷方式,但根据经验,支架不适合生产。
就个人而言,我没有看到太多代码至少没有进行基本验证。我认为这有点文化:如果你没有创建一个会引发错误的路线,你没有义务处理它。显然这远非理想,但我认为不是许多开发人员的优先事项。这主要取决于业务逻辑:它通常是正向的,即只考虑响应用户有效的操作。
答案 2 :(得分:0)
因为它更容易调用:
Model.find_by_id(params[:id])
如果没有找到记录,则返回nil
答案 3 :(得分:0)
因为你想要fail early。你越早发现错误,就越早解决问题。
答案 4 :(得分:0)
我见过这样的代码:
def add_to_cart
begin
product = Product.find(params[:id])
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid product #{params[:id]}")
redirect_to_index("Invalid product")
else
@cart = find_cart
@cart.add_product(product)
end
end