[英]Rails respond_with: how does it work?
我一直在这里和那里阅读关于 Rails 3 中的respond_with
方法有多酷。但我什至在 Rails API 或搜索源代码中都找不到对它的引用。 任何人都可以向我解释它是如何工作的(您可以使用哪些选项等),或者将我指向它实际实现的位置,以便我可以自己仔细阅读代码?
#respond_with
和::respond_to
( nb class 方法)不再是 Rails 的一部分。 从 Rails 4.2 开始,它们被迁移到第三方响应者gem( 发布说明/2014 年 8 月提交)。 虽然响应者默认不包含在 Rails 中,但它是 Devise 的依赖项,因此可在许多 Rails 应用程序中使用。
然而, #respond_to
实例方法仍然是 Rails 的一部分(撰写本文时为 5.2rc1)。
ActionController::MimeResponds
的官方 Rails API 文档解释了#respond_to
工作原理。 #respond_with
和::respond_to
的原始 Rails Guides 文档注释仍然可以在响应者 gem 源代码中找到。
响应者的代码基于 class 和模块。 包含在ActionController::Base中的MimeResponds ,class 您的ApplicationController
继承自。 然后是ActionController::Responder ,它在使用 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
这是一个包含响应者的 class 属性。 这可以是响应调用的任何内容,这意味着您可以使用响应调用的 proc/lambda 或 class。 另一种选择是将一个或多个模块混合到现有响应程序中以重载现有方法,从而增强默认行为。
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
虽然可能有一些有趣的边缘用例,但将模块扩展或混合到默认响应者中更有可能是更常见的模式。 在任何情况下,相关的选项都是资源和选项,因为它们是从 from respond_with 传递过来的。
respond_with
这里的选项是那些将被传递给 controller 中的 render 或 redirect_to 的选项,但它们仅包含在成功场景中。 对于 GET 操作,这些将是渲染调用,对于其他操作,这将是重定向的选项。 其中最有用的可能是:location
选项,它可用于覆盖该重定向路径,以防 respond_with 的 arguments 不足以构建正确的 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'))
作为替代方案,响应者gem 不仅提供了一些模块来覆盖一些默认行为。 它使用扩展默认响应器的匿名 class 覆盖默认响应器,并提供 class 级别的方法来混合自定义模块到此 class。 这里最有用的是 flash 响应程序,它提供了一组默认的 flash,将自定义委托给 I18n 系统,默认为config/locales/en.yml
。
我在以前的项目中使用的一些自定义响应器示例包括一个响应器,它自动修饰我的资源,并提供一组默认的页面标题和一个用于轻松自定义或覆盖页面标题的界面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.