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

Tet*_*suo 12 format rest mime ruby-on-rails render

我有一个只有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模板?

Tob*_*ede 14

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

map.connect ':controller/:action/:id.:format'
Run Code Online (Sandbox Code Playgroud)

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


lev*_*han 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
Run Code Online (Sandbox Code Playgroud)

:除了和:只有选项

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

class UsersController < ApplicationController::Base
  respond_to :html, :only => :index
  respond_to :xml, :json, :except => :show
  ...
end
Run Code Online (Sandbox Code Playgroud)

:任何格式

如果您仍希望在个别操作中使用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
Run Code Online (Sandbox Code Playgroud)


Ben*_*Ben 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
Run Code Online (Sandbox Code Playgroud)

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

  • 但实际上并没有返回404,它只是将'404.html`作为200响应.你需要添加`:status => 404`(或`:status =>:not_found`).类似地,对于406,您将要使用`:status => 406`(或`:status =>:not_acceptable`). (2认同)

Jon*_*ian 5

Ben的解决方案有效.

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

skip_before_filter :allow_only_html_requests, :only => [:show]
Run Code Online (Sandbox Code Playgroud)

我个人喜欢respond_to块; 它非常具有描述性.

respond_to do |wants|
  wants.html
 end
Run Code Online (Sandbox Code Playgroud)

块中未指定的任何格式将自动导致返回HTTP 406 Not Acceptable.真好.