在构建Sinatra或Padrino应用程序时,我经常编写类似
的代码get '/resource/:id' do
resource = Resource.find(params[:id])
return status 404 if resource.nil?
# ..
end
或者实际上,我喜欢
flash[:warning] = "A Resource with id #{params[:id]} coud not be found".
redirect back
我认为在Rails中这是通过" Ressources"建模的。我的控制器往往是混合的,部分路由将取决于资源ID(将从任何数据库中获取),其他不需要。
可以使用哪种模式来干这个?我知道before
处理程序
(伪代码,但还没有看到一个非常聪明的实现 - 它肯定在某处!)
before "*" do
@resource = Resource.get(params[:id])
redirect_with_flash if @resource.nil?
end
或将类似的代码放在方法中,以便在具有该要求的每条路线中首先调用。
尽管如此,我在几乎所有的Sinatra教程中都看到了类似的代码,是不是有更好的选择?如果我忽略它,我对padrino方法特别感兴趣。
以下是我希望的代码看起来像
MyPadrinoApp::App.controllers :user do
associated_resource = User
associated_resource_error_flashs = { "404": "A User with %s could not be found" }
get :show, :with => :id, :resource_bound => :user do
render '/user/show' # in which @user is available
end
end
答案 0 :(得分:2)
如果您想在知道请求无效/发生错误后立即停止处理请求,则可以使用Sinatras halt
。它会立即停止进一步处理,并允许您定义http状态代码和要显示的消息,如果您的App不是REST API,则可以定义相应的错误模板。
在您的示例中,请求变为无效,因为请求的资源不存在。使用404回答是正确的,您可以告诉halt
在响应中使用此状态代码。
一个非常简单的实现可能如下所示:
get '/resource/:id' do
resource = Resource.find(params[:id])
halt 404, "A Resource with id #{params[:id]} could not be found" if resource.nil?
# ..
end
更优雅的方法是使用辅助方法加载资源,该方法关注错误处理,您最好在所有路由中使用相同的调用。
helpers do
def load_resource
Resource.find(params[:id]) || halt(404, "A Resource with id #{params[:id]} could not be found")
end
end
get '/resource/:id' do
# load the resource via helper method
resource = load_resource
# if the resource doesn't exists, the request and processing is already dropped
..
end
halt
还有更多输出选项,如上所述,您可以返回erb模板,也可以返回JSON而不是纯文本等等。 Check the docs here