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

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

www.mysite.com/jobs/1

它呈现我的html工作,但是,如果我要求:

www.mysite.com/jobs/1.xml

我收到错误:

模板丢失在视图路径c:/ workspace / mysite / app / views中缺少模板jobs / show.xml.erb

更糟糕的是,我也可以请求类似的东西

www.mysite.com/jobs/1.xyz

事实上,我看到了错误:

模板丢失在视图路径c:/ workspace / mysite / app / views中缺少模板作业/ show.xyz.erb

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

重要的是要注意:

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

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

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

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

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

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

您可以使用Rails Per-Action Overwritefunction。 这是什么? – >也可以通过传入一个块来响应标准资源处理,以响应为该操作指定要覆盖的格式:

 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 

:除了和:只有选项

您还可以传入: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 

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。 真好。

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

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

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