13

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

www.mysite.com/jobs/1

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

www.mysite.com/jobs/1.xml

我得到错误:

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

更糟糕的是,我还可以要求类似的东西

www.mysite.com/jobs/1.xyz

确实我看到了错误:

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

要严格呈现 html 内容,告诉 Rails 我不想呈现 .html.erb 文件以外的任何内容的最简洁和最简单的方法是什么。

需要注意的是:

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

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

4

5 回答 5

14

在您的路线中,您可以简单地删除该行:

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

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

于 2009-11-04T01:08:52.190 回答
10

您可以使用 Rails Per-Action Overwrite功能。这是什么?--> 还可以通过将块传递给 respond_with 来覆盖标准资源处理,以指定该操作要覆盖的格式:

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 选项

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

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

:any 格式

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

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
于 2010-03-18T13:43:36.213 回答
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。

于 2009-11-04T01:13:32.517 回答
5

本的解决方案有效。

不过,请考虑 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。那很好。

于 2009-11-04T21:30:40.177 回答
1

我收到了对 HTML 文件的图像格式无意义的请求,触发了 500 和MissingTemplate. 在我的行动结束时,我制定了以下内容:

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

现在我们没有收到错误报告,而是向那个淘气的请求者发出 406。

于 2016-01-28T23:26:46.943 回答