我到处都在读Rails 3中的respond_with
方法有多酷.我甚至无法在Rails或源代码中找到它.有没有人可以向我解释一下它是如何工作的(你可以使用什么选项等等),或者告诉我它实际实现的地方,这样我就可以自己阅读代码了?
我到处都在读Rails 3中的respond_with
方法有多酷.我甚至无法在Rails或源代码中找到它.有没有人可以向我解释一下它是如何工作的(你可以使用什么选项等等),或者告诉我它实际实现的地方,这样我就可以自己阅读代码了?
#respond_with
和::respond_to
(n.b.类方法)是no longer a part of Rails.从Rails 4.2(2014年8月发布的release notes/commit)起,它们被移植到第三方responders gem中.虽然默认情况下Rails中不包含响应程序,但它依赖于Desive,因此在许多Rails应用程序中都可用.
然而,#respond_to
instance method,是still a part of Rails(截至本文 compose 时为5.2rc1).
ActionController::MimeResponds
的官方Rails API文档解释了#respond_to
的工作原理.#respond_with
和::respond_to
的原始Rails指南文档注释仍然可以在responders gem source code中找到.
响应者的代码基于类和模块.MimeResponds包含在ActionController::Base中,即ApplicationController
继承的类.然后是ActionController::Responder,它提供了使用respond_with时的默认行为.
默认情况下,rails在响应中提供的唯一行为是隐式try 呈现名称与操作匹配的模板.除此之外,任何操作都需要更多指令,或者需要一个自定义的respond_调用一个块来处理多个格式响应.
由于大多数控制器使用一种相当常见的定制模式,响应者通过引入更多默认行为来提供额外的抽象级别.阅读调用_xml/to_json以获取特定格式的操作,以及提供相同格式的mutator操作,以及成功执行mutator操作的重定向.
有一些机会可以定制响应者的行为,从细微的调整到完全覆盖或扩展行为.
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或响应调用的类.另一种 Select 是将一个或多个模块混合到现有响应程序中,以重载现有方法,从而增强默认行为.
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_传递的.
respond_with
这里的选项是那些将被传递到控制器中渲染或重定向到的选项,但它们仅用于成功场景.对于GET操作,这些将是呈现调用,对于其他操作,这些将是重定向选项.在这种情况下,这些参数中的哪一个可能不足以覆盖正确的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'))
作为替代方案,responders gem不仅提供了一些用于覆盖某些默认行为的模块.它用一个扩展默认响应程序的匿名类覆盖默认响应程序,并提供一个类级方法,用于将自定义模块混合到该类中.这里最有用的是flash responder,它提供了一组默认的flash,默认情况下将定制委托给I18n系统config/locales/en.yml
.
我在以前的项目中使用过的一些自定义响应程序示例包括一个自动修饰我的资源的响应程序,并提供了一组默认的页面标题,带有一个界面,可以轻松自定义或覆盖页面标题.