如何将我的Rails控制器设置为默认只接受HTML请求?

时间:2014-01-27 16:46:22

标签: ruby-on-rails

我的大多数控制器只在HTML中有有意义的响应。请考虑以下情形:

我制作一个简单的控制器

class FrontController < ApplicationController
  def index
  end
end

并提供app/views/front/index.html.erb。如果我使用Accept: text/html点击该操作,则会按预期呈现该模板。

如果我使用Accept: application/xml点击该操作,我想获得406 Not Acceptable。相反,Rails会引发ActionView::MissingTemplate异常,并显示500错误:

  

缺少模板前/索引,应用程序/索引{:locale =&gt; [:en],:formats =&gt; [:xml],:handlers =&gt; [:erb,:builder,:raw,: ruby,:jbuilder,:coffee]}。


我有两种方法可以从控制器中获取406 Not Acceptable。首先,我可以使用respond_to块:

class FrontController < ApplicationController
  def index
    respond_to do |f|
      f.html
    end
  end
end

其次,我可以使用respond_with,虽然在不代表资源的控制器中看起来很奇怪:

class FrontController < ApplicationController
  respond_to :html

  def index
    respond_with # No arguments, because there's nothing to put here.
  end
end

其中任何一个都会响应406的XML请求。但是,两者都需要为每个控制器操作添加代码。


以下是我希望能够做到的事情:

  • 理想情况下,如果找不到模板,我想要隐式呈现(没有render调用或声明显式格式)的操作返回406。对于Rails来说,这似乎是一个合理的默认值,我很惊讶它不会那样做。

  • 如果做不到这一点,我至少希望能够默认将:html声明为所有控制器的唯一可接受格式(并且让各个控制器和操作中的任何显式格式声明都覆盖)。

想法?

(Rails 4.0.1,Ruby 2.0.0)

1 个答案:

答案 0 :(得分:0)

如果您不想使用responds_to,可以这样做:

class ApplicationController < ActionController::Base
  before_filter :allow_only_html_requests

  ...

  def allow_only_html_requests
    if params[:format] && params[:format] != 'html'
      render :file => "#{RAILS_ROOT}/public/404.html"
    end
  end

  ...

end