Ruby-on-rails Rails response_with:它是如何工作的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6118639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails respond_with: how does it work?
提问by jaydel
I've been reading here and there about how cool the respond_withmethod is in Rails 3. But I can't even find a reference to it in either the Rails APIs or by searching the source. Can anyone either explain to me how it works (what options you can use, etc) or point me to the place it's actually implemented so I can peruse the code on my own?
我一直在这里和那里阅读有关该respond_with方法在 Rails 3 中有多酷的信息。但我什至无法在 Rails API 中或通过搜索源找到对它的引用。任何人都可以向我解释它是如何工作的(您可以使用哪些选项等)或将我指向它实际实现的地方,以便我可以自己仔细阅读代码?
回答by Cluster
Update for Rails 4.2+
Rails 4.2+ 的更新
#respond_withand ::respond_to(n.b.class method) are no longer a part of Rails. They were migrated into the third-party respondersgem as of Rails 4.2 (release notes/ commitdated Aug 2014). While responders is not included in Rails by default, it is a dependency of Devise, and thus available in many Rails applications.
#respond_with和::respond_to(nb类方法)不再是 Rails 的一部分。从 Rails 4.2开始,它们被迁移到第三方响应者gem(发布说明/提交日期为 2014 年 8 月)。虽然默认情况下响应器不包含在 Rails 中,但它是 Devise 的依赖项,因此在许多 Rails 应用程序中可用。
The #respond_toinstance method,however, is still a part of Rails(5.2rc1 as of this writing).
的#respond_to实例方法,然而,仍然轨道的一部分(5.2rc1撰写本文时)。
The official Rails API documentation for ActionController::MimeRespondsexplains how #respond_toworks. The original Rails Guides documentation comments for #respond_withand ::respond_tocan still be found in the responders gem source code.
官方 Rails API 文档ActionController::MimeResponds解释了如何#respond_to工作。对于原来的Rails指南文档注释#respond_with,并::respond_to仍然可以在发现应答宝石的源代码。
Original Answer
原答案
The code for the responders is based in a class and a module. MimeRespondswhich is included into ActionController::Base, the class your ApplicationControllerinherits from. Then there is ActionController::Responderwhich provides the default behavior when using respond_with.
响应者的代码基于一个类和一个模块。MimeResponds包含在ActionController::Base 中,您ApplicationController继承的类。然后是ActionController::Responder,它提供了使用 response_with 时的默认行为。
By default, the only behavior rails provides in the response is an implicit attempt to render a template with a name matching the action. Anything beyond that requires more instructions within the action, or a custom respond_to call with a block to handle multiple format responses.
默认情况下,rails 在响应中提供的唯一行为是隐式尝试呈现名称与操作匹配的模板。除此之外的任何操作都需要在操作中使用更多指令,或者使用块来调用自定义响应_to 来处理多种格式的响应。
As most controllers use a fairly common pattern of customization, responders provide an extra level of abstraction by introducing more default behavior. Read actions calling to_xml/to_json for specific formats, and mutator actions providing the same as well as redirects for successful mutator actions.
由于大多数控制器使用相当常见的定制模式,响应者通过引入更多默认行为来提供额外的抽象级别。读取针对特定格式调用 to_xml/to_json 的操作,以及为成功的 mutator 操作提供相同和重定向的 mutator 操作。
There are a few opportunities to customize how responders behave, from subtle tweaks to completly overriding or extending the behavior.
有一些机会可以自定义响应者的行为方式,从细微的调整到完全覆盖或扩展行为。
Class Level: respond_to
班级: respond_to
Here you specify the formats that the Responder should handle. The formats can be customized as to which actions they will apply to. Each format can be specified with separate calls, allowing complete customization of the actions for each format.
在此指定响应程序应处理的格式。可以自定义格式以了解它们将应用于哪些操作。可以使用单独的调用指定每种格式,从而可以完全自定义每种格式的操作。
# 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]
Class Level: responder
班级: responder
This is a class attribute that holds the responder. This can be anything that responds to call, which means you can use a proc/lambda or a class that responds to call. Another alternative is to mixin one or modules to the existing responder to overload existing methods, augmenting the default behavior.
这是一个包含响应者的类属性。这可以是响应调用的任何东西,这意味着您可以使用 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
While there may be some interesting edge use cases, it's more likely that extending or mixing modules into the default responder would be more common patterns. In any case, the options that are relevant are the resources and options, as they are passed through from the from respond_with.
虽然可能有一些有趣的边缘用例,但将模块扩展或混合到默认响应器中更有可能是更常见的模式。在任何情况下,相关的选项是资源和选项,因为它们是从 response_with 传递过来的。
Instance Level: respond_with
实例级别: respond_with
The options here are those that would be passed to render or redirect_to in your controller, but they are only included for success scenarios. For GET actions these would be the render calls, for other actions this would be the options for redirect. Probably the most useful of these is the :locationoption, which can be used to override that redirect path in case the arguments for respond_with are not sufficient to build the right URL.
这里的选项是那些将传递给控制器中的 render 或 redirect_to 的选项,但它们仅包含在成功场景中。对于 GET 操作,这些将是渲染调用,对于其他操作,这将是重定向的选项。其中最有用的可能是:location选项,它可用于覆盖重定向路径,以防 response_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'))
As an alternative, the respondersgem not only provides some modules for overriding some of the default behavior. It overrides the default responder with an anonymous class that extends the default responder, and provides a class level method for mixing in custom modules to this class. The most useful here is the flash responder, which provides a default set of flashes, delegating customization to the I18n system, config/locales/en.ymlby default.
作为替代方案,响应者gem 不仅提供了一些模块来覆盖一些默认行为。它使用扩展默认响应器的匿名类覆盖默认响应器,并提供类级方法用于将自定义模块混合到此类中。这里最有用的是 flash 响应器,它提供一组默认的 flash,默认情况下将自定义委托给 I18n 系统config/locales/en.yml。
Some examples of custom responders I've used in previous projects include a responder that automatically decorated my resources, and provided a default set of page titles with an interface for easily customizing or overriding the page title.
我在之前的项目中使用过的一些自定义响应程序示例包括一个自动装饰我的资源的响应程序,并提供一组默认的页面标题以及一个界面,以便轻松自定义或覆盖页面标题。

