Ruby on rails 需要在Rails中返回JSON格式的404错误

Ruby on rails 需要在Rails中返回JSON格式的404错误,ruby-on-rails,Ruby On Rails,我的Rails应用程序中有一个普通的HTML前端和一个JSON API。现在,如果有人调用/api/not_existence\u method.json,它将返回默认的HTML404页面。在保留HTML前端的原始404页面不变的情况下,是否有任何方法将其更改为类似于{“error”:“not_found”} class ApplicationController < ActionController::Base rescue_from NotFoundException, :with

我的Rails应用程序中有一个普通的HTML前端和一个JSON API。现在,如果有人调用
/api/not_existence\u method.json
,它将返回默认的HTML404页面。在保留HTML前端的原始404页面不变的情况下,是否有任何方法将其更改为类似于
{“error”:“not_found”}

class ApplicationController < ActionController::Base
  rescue_from NotFoundException, :with => :not_found
  ...

  def not_found
    respond_to do |format|
      format.html { render :file => File.join(Rails.root, 'public', '404.html') }
      format.json { render :text => '{"error": "not_found"}' }
    end
  end
end
# In your config/application.rb
config.exceptions_app = self.routes
class ApplicationController:未找到
...
未找到def
回应待办事项|格式|
format.html{render:file=>file.join(Rails.root,'public','404.html')}
format.json{render:text=>'{“错误”:“未找到”}
结束
结束
结束

NotFoundException
不是异常的真实名称。它将随Rails版本和您想要的确切行为而变化。通过谷歌搜索很容易找到。

尝试将放在
路线的末尾。rb

match '*foo', :format => true, :constraints => {:format => :json}, :to => lambda {|env| [404, {}, ['{"error": "not_found"}']] }
get "/404" => "errors#not_found"
get "/500" => "errors#exception"

一位朋友向我推荐了一个优雅的解决方案,它不仅可以处理404个错误,还可以处理500个错误。事实上,它可以处理每一个错误。关键是,每个错误都会生成一个异常,该异常会通过机架中间件堆栈向上传播,直到由其中一个处理。如果你对学习更多感兴趣,你可以观看。Rails有自己的异常处理程序,但您可以通过文档较少的
exceptions\u app
config选项覆盖它们。现在,您可以编写自己的中间件,也可以将错误路由回rails,如下所示:

class ApplicationController < ActionController::Base
  rescue_from NotFoundException, :with => :not_found
  ...

  def not_found
    respond_to do |format|
      format.html { render :file => File.join(Rails.root, 'public', '404.html') }
      format.json { render :text => '{"error": "not_found"}' }
    end
  end
end
# In your config/application.rb
config.exceptions_app = self.routes
然后您只需在
config/routes.rb中匹配这些路由即可:

match '*foo', :format => true, :constraints => {:format => :json}, :to => lambda {|env| [404, {}, ['{"error": "not_found"}']] }
get "/404" => "errors#not_found"
get "/500" => "errors#exception"
然后你只需要创建一个控制器来处理这个问题

class ErrorsController < ActionController::Base
  def not_found
    if env["REQUEST_PATH"] =~ /^\/api/
      render :json => {:error => "not-found"}.to_json, :status => 404
    else
      render :text => "404 Not found", :status => 404 # You can render your own template here
    end
  end

  def exception
    if env["REQUEST_PATH"] =~ /^\/api/
      render :json => {:error => "internal-server-error"}.to_json, :status => 500
    else
      render :text => "500 Internal Server Error", :status => 500 # You can render your own template here
    end
  end
end

我想创建一个单独的API控制器,用于设置格式(json)和特定于API的方法:

class ApiController < ApplicationController
  respond_to :json

  rescue_from ActiveRecord::RecordNotFound, with: :not_found
  # Use Mongoid::Errors::DocumentNotFound with mongoid

  def not_found
    respond_with '{"error": "not_found"}', status: :not_found
  end
end

感谢您的想法,但我使用的是Rails 3.2.2,其中异常处理发生了变化。这将不再有效。@iblue这在Rails 3.2+中工作得很好,是更好的解决方案。有关更多信息,请参见
中的
rescue\u。另外,不要忘记将状态代码添加到渲染中。否则,您的客户端/浏览器将不知道它是404/500。render:text=>“404未找到”,:status=>:not_found我想说respond_to block在呈现函数中更通用:respond_to do | format | format.json{render json:{error:{not found}。to_json,status:404}format.html{render text:“404 not found”,status:404}endI已命名了我的API控制器,并引发了一个异常,该异常具有类似ApiException的基类,然后可以在基本命名的API控制器中进行解救,在该控制器中,可以返回一个JSON友好的错误,并返回相应的状态,如上所述。@RichardHollis我的API控制器也有名称空间,但我能实现您所做的吗?在使用上述建议的解决方案之前,请查看此答案:。在祖先控制器中捕获404并使用回调做出简单的JSON错误响应要简单得多。这似乎只适用于记录。您将如何管理
api/non\u existant\u route
的案例?行
rescue\u from ActiveRecord::RecordNotFound,with:not\u found
需要
with::not\u found
但对于其他阅读此内容的人来说,这只是一个字符的编辑:,
Rails.application.routes
文件中的
match
现在要求您通过
via:
参数指定HTTP方法。当您尝试使用上述行时,这也将显示为错误。