将Rails渲染格式限制为html的方法

时间:2009-11-04 00:51:57

标签: ruby-on-rails rest format mime render

我有一个只有html模板的Rails 2.1.2网站,例如jobs.html.erb,所以当我请求一个宁静的资源时:

  

www.mysite.com/jobs/1

如果我要求,它会以html呈现我的工作:

  

www.mysite.com/jobs/1.xml

我收到错误:

  

缺少模板缺少模板   视图路径中的jobs / show.xml.erb   C:/工作区/ mysite的/应用/视图

更糟糕的是,我还可以请求类似

的内容
  

www.mysite.com/jobs/1.xyz

确实我看到了错误:

  

缺少模板缺少模板   视图路径中的jobs / show.xyz.erb   C:/工作区/ mysite的/应用/视图

要严格地呈现html内容,告诉Rails最简洁,最简单的方法是除了.html.erb文件之外我不想呈现任何内容。

重要的是要注意:

  • 我的一些控制器动作包含对render()方法的条件调用,而其他人使用默认的Rails行为,即如果你不调用render(),那么将呈现名为youraction.html.erb的模板。
  • 我的代码不使用responds_to()方法

如果解决方案不在render / responds_to级别,那将是很好的,因为我必须修改大量的操作。也许有一种方法可以配置Rails以便只呈现html模板?

5 个答案:

答案 0 :(得分:14)

在您的路线中,您只需删除该行:

map.connect ':controller/:action/:id.:format'

“.xyz”将不再被路由,导致404错误/.

答案 1 :(得分:10)

您可以使用Rails Per-Action Overwrite 功能。这是什么? - >也可以通过传入一个块来响应标准资源处理,以响应为该操作覆盖哪些格式:

class UsersController < ApplicationController::Base

  respond_to :html, :xml, :json

  # Override html format since we want to redirect to a different page,
  # not just serve back the new resource
  def create
    @user = User.create(params[:user])
    respond_with(@user) do |format|
      format.html { redirect_to users_path }
    end
  end
end

:除了And:只有选项

您还可以传入:except和:only选项仅支持特定操作的格式(与before_filter一样):

class UsersController < ApplicationController::Base
  respond_to :html, :only => :index
  respond_to :xml, :json, :except => :show
  ...
end

:任何格式

如果您仍想在各自的操作中使用respond_to,请使用:任何可用作任何未指定格式的通配符匹配的资源格式:

class UsersController < ApplicationController::Base

  def index

    @users = User.all

    respond_to do |format|
      format.html
      format.any(:xml, :json) { render request.format.to_sym => @users }
    end
  end
end

答案 2 :(得分:7)

如果您不想使用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

这将在所有请求之前运行,并且只允许那些没有指定格式或者指定html格式的那些请求。所有其他人获得404'd。如果要返回406,则可以创建public / 406.html。

答案 3 :(得分:5)

Ben的解决方案有效。

考虑一下responds_to解决方案。它更清晰,因为当您不可避免地需要为JavaScript json或xml调用打开一个动作时它允许灵活性。然后你不必添加

skip_before_filter :allow_only_html_requests, :only => [:show]

我个人喜欢respond_to块;这是非常具有描述性的。

respond_to do |wants|
  wants.html
 end

块中未指定的任何格式将自动导致返回HTTP 406 Not Acceptable。那太好了。

答案 4 :(得分:1)

我在HTML文件上获得了对图像格式的非感性请求,触发了MissingTemplate的500。我在行动结束时对以下内容进行了编辑:

def show
  # [...]
  respond_to :html
end

现在我们不会收到错误报告,而是向那个恶作剧请求者发出406。