Ruby on rails Rails使用jbuilder显示错误的正确方法

Ruby on rails Rails使用jbuilder显示错误的正确方法,ruby-on-rails,ruby,json,jbuilder,Ruby On Rails,Ruby,Json,Jbuilder,我希望在jbuilder视图中显示错误消息。例如,我可能有一条路线: /foos/:id/bar 如果用户提交的:id不存在或无效,我希望能够在我的index.json.builder文件中相应地显示错误消息 使用Rails,最好的方法是什么?控制器可能具有以下内容: def index @bar = Bar.where(:foo_id => params[:id]) end 在这种情况下,params[:id]可能是nil,或者该对象可能不存在。我不确定这里最好的方法是在控制器中处

我希望在jbuilder视图中显示错误消息。例如,我可能有一条路线:

/foos/:id/bar

如果用户提交的
:id
不存在或无效,我希望能够在我的
index.json.builder
文件中相应地显示错误消息

使用Rails,最好的方法是什么?控制器可能具有以下内容:

def index
  @bar = Bar.where(:foo_id => params[:id])
end

在这种情况下,
params[:id]
可能是
nil
,或者该对象可能不存在。我不确定这里最好的方法是在控制器中处理它并显式呈现
error.json.builder
,还是在
index.json.builder
视图本身中处理它。正确的方法是什么?如果在
index.json.builder
中,是否可以在那里检查
params[:id]
?我知道我可以看到是否
@bar.nil?
,但不确定是否相反?

我会渲染index.json.builder,或者只使用
内联json:error=>“找不到”
不要忘记设置正确的HTTP状态:
:status=>404

所以结果可能是这样的:

render :json => { :error => 'not found' }, :status => 422 if @bar.nil?

我想你的意思是显示,因为索引实际上是用于列表/集合的。你应该先在where上找到
。否则你就只有一个关系了,对吗?然后,首先使用
引发错误,因为Rails 4中的Rails机架中间件将以基本方式处理,例如

def show
  # need to do to_s on params value if affected by security issue CVE-2013-1854
  @bar = Bar.where(:foo_id => params[:id].to_s).first!
end
您也可以使用
@bar=bar.find(params[:id])
,但这已被弃用,将在Rails 4.1中删除,之后您必须将
gem'activerecord-deprecated_finders'
添加到gem文件中才能使用

对于索引,您可能需要
@Bar=Bar.all
。如果出于某种原因,您想筛选,但不想确定范围,等等,那么您可以使用
@Bar=Bar.where(…)来搜索
或类似内容

Rails 4:机架中的基本异常处理是自动的 只要查询启动了一个错误,Rails 4就应该能够返回错误的消息部分,因为任何支持的格式
where to(format)
都可以在散列上调用(例如json、xml等)

要了解原因,请查看Rails的机架中间件

如果是html,它将尝试从Rails的公共目录中读取状态代码的相关文件(例如,服务器错误/HTTP 500的
500.html

如果是其他格式,它将尝试在哈希上执行
{:status=>status,:error=>exception.message}
。要了解这将如何工作,请转到Rails的控制台:

$ rails c
...
1.9.3p392 :001 > {status: 500, error: "herro shraggy!"}.to_xml
 => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n  <status type=\"integer\">500</status>\n  <error>herro shraggy!</error>\n</hash>\n" 
1.9.3p392 :002 > {status: 500, error: "herro shraggy!"}.to_json
 => "{\"status\":500,\"error\":\"herro shraggy!\"}" 
注意:对于该处理中的任何问题,故障保护实现在
ActionDispatch::ShowExceptions

Rails 3和4:在Rails控制器中处理一些异常 如果希望在控制器本身中呈现错误,可以执行以下操作:

def show
  respond_with @bar = Bar.where(:foo_id => params[:id].to_s).first!
rescue ActiveRecord::RecordNotFound => e
  respond_to do |format|
    format.json => { :error => e.message }, :status => 404
  end
end
但是,您不需要提出错误。你也可以这样做:

def show
  @bar = Bar.where(:foo_id => params[:id].to_s).first
  if @bar
    respond_with @bar
  else
    respond_to do |format|
      format.json => { :error => "Couldn't find Bar with id=#{params[:id]}" }, :status => 404
    end
  end
end
您还可以在控制器或应用程序控制器等中使用:

rescue_from ActiveRecord::RecordNotFound, with: :not_found

def not_found(exception)
  respond_to do |format|
    format.json => { :error => e.message }, :status => 404
  end
end
或:

虽然一些常见错误可以在控制器中处理,但如果您发现与json格式的丢失路由等相关的错误,则需要在机架中间件中处理这些错误

rescue_from ActiveRecord::RecordNotFound, with: :not_found

def not_found(exception)
  respond_to do |format|
    format.json => { :error => e.message }, :status => 404
  end
end
rescue_from ActiveRecord::RecordNotFound do |exception|
  respond_to do |format|
    format.json => { :error => e.message }, :status => 404
  end
end