Rails 4.2+ 更新
#respond_with
and ::respond_to
(n.b.类方法)是不再是 Rails 的一部分。他们被迁移到第三方响应者 https://github.com/plataformatec/responders从 Rails 4.2 开始的 gem (发行说明 http://guides.rubyonrails.org/4_2_release_notes.html#respond-with-class-level-respond-to / commit https://github.com/rails/rails/commit/ee77770d57de9da87b05a2fe84b9d46ec6852c62#diff-bb9b4c4885f0fec7dd7766455423d401日期为 2014 年 8 月)。虽然默认情况下,Rails 中不包含响应程序,但它是 Devise 的依赖项,因此可在许多 Rails 应用程序中使用。
The #respond_to
实例方法,然而,是仍然是 Rails 的一部分(截至撰写本文时为 5.2rc1)。
官方 Rails API 文档ActionController::MimeResponds http://edgeapi.rubyonrails.org/classes/ActionController/MimeResponds.html解释如何#respond_to
作品。原始 Rails Guides 文档注释#respond_with
and ::respond_to
仍然可以找到响应者宝石源代码 https://github.com/plataformatec/responders/blob/master/lib/action_controller/respond_with.rb.
原答案
响应者的代码基于类和模块。哑剧回应 https://github.com/rails/rails/blob/v3.2.12/actionpack/lib/action_controller/metal/mime_responds.rb包含在动作控制器::基础 https://github.com/rails/rails/blob/v3.2.12/actionpack/lib/action_controller/base.rb#L196,你的班级ApplicationController
继承自.然后有动作控制器::响应者 https://github.com/rails/rails/blob/v3.2.12/actionpack/lib/action_controller/metal/responder.rb它提供了使用 respond_with 时的默认行为。
默认情况下,rails 在响应中提供的唯一行为是隐式尝试渲染名称与操作匹配的模板。除此之外的任何操作都需要操作中的更多指令,或者使用块来调用自定义的 respond_to 来处理多种格式响应。
由于大多数控制器使用相当常见的自定义模式,因此响应程序通过引入更多默认行为来提供额外的抽象级别。读取针对特定格式调用 to_xml/to_json 的操作,以及提供相同格式的突变操作以及成功突变操作的重定向。
有一些机会可以定制响应者的行为方式,从细微的调整到完全覆盖或扩展行为。
班级级别:respond_to
您可以在此处指定响应程序应处理的格式。可以自定义格式以决定它们将应用于哪些操作。每种格式都可以通过单独的调用来指定,从而允许完全自定义每种格式的操作。
# Responds to html and json on all actions
respond_to :html, :json
# Responds to html and json on index and show actions only.
respond_to :html, :json, :only => [:index,:show]
# Responds to html for everything except show, and json only for index, create and update
respond_to :html, :except => [:show]
respond_to :json, :only => [:index, :create, :update]
班级级别:responder
这是保存响应者的类属性。这可以是响应调用的任何内容,这意味着您可以使用 proc/lambda 或响应调用的类。另一种选择是将一个或多个模块混合到现有响应程序中以重载现有方法,从而增强默认行为。
class SomeController < ApplicationController
respond_to :json
self.responder = proc do |controller, resources, options|
resource = resources.last
request = controller.request
if request.get?
controller.render json: resource
elsif request.post? or request.put?
if resource.errors.any?
render json: {:status => 'failed', :errors => resource.errors}
else
render json: {:status => 'created', :object => resource}
end
end
end
end
虽然可能存在一些有趣的边缘用例,但将模块扩展或混合到默认响应程序中更有可能是更常见的模式。无论如何,相关的选项是资源和选项,因为它们是从respond_with 传递过来的。
实例级别:respond_with
这里的选项是那些将传递给控制器中的 render 或 redirect_to 的选项,但它们仅包含在成功场景中。对于 GET 操作,这些将是渲染调用,对于其他操作,这将是重定向选项。其中最有用的可能是:location
选项,可用于覆盖该重定向路径,以防 respond_with 的参数不足以构建正确的 URL。
# These two are essentially equal
respond_with(:admin, @user, @post)
respond_with(@post, :location => admin_user_post(@user, @post)
# Respond with a 201 instead of a 200 HTTP status code, and also
# redirect to the collection path instead of the resource path
respond_with(@post, :status => :created, :location => posts_path)
# Note that if you want to pass a URL with a query string
# then the location option would be needed.
# /users?scope=active
respond_with(@user, :location => users_path(:scope => 'active'))
作为替代方案,响应者 https://github.com/plataformatec/respondersgem 不仅提供了一些用于覆盖某些默认行为的模块。它使用扩展默认响应程序的匿名类覆盖默认响应程序,并提供类级别方法以将自定义模块混合到此类中。这里最有用的是 flash 响应器,它提供了一组默认的 flash,将自定义委托给 I18n 系统,config/locales/en.yml
默认情况下。
我在以前的项目中使用的自定义响应程序的一些示例包括自动装饰我的资源的响应程序,并提供一组默认的页面标题和一个用于轻松自定义或覆盖页面标题的界面。