Rails respond_with:它是如何工作的?

时间:2011-05-25 01:34:44

标签: ruby-on-rails ruby-on-rails-3

我一直在这里阅读有关Rails 3中respond_with方法有多酷的内容。但我甚至无法在Rails API或搜索源中找到它的引用。任何人都可以向我解释它是如何工作的(您可以使用哪些选项等)或指向我实际实现的地方,以便我可以自己仔细阅读代码?

1 个答案:

答案 0 :(得分:118)

Rails 4.2 +

的更新

#respond_with::respond_to n.b。类方法)不再是Rails的一部分。从Rails 4.2(2014年8月responders / release notes开始),它们被迁移到第三方commit宝石中。虽然默认情况下响应者不包含在Rails中,但它是Devise的依赖,因此可以在许多Rails应用程序中使用。

然而,#respond_to 实例方法 仍然是Rails的一部分(截至撰写本文时为5.2rc1)。

ActionController::MimeResponds的官方Rails API文档解释了#respond_to的工作原理。 #respond_with::respond_to的原始Rails指南文档评论仍可在responders gem source code中找到。


原始答案

响应者的代码基于类和模块。 MimeResponds包含在ActionController::Base中,ApplicationController继承自的类respond_to。然后有ActionController::Responder,它在使用respond_with时提供默认行为。


默认情况下,响应中提供的唯一行为是隐式尝试呈现名称与操作匹配的模板。除此之外的任何内容都需要操作中的更多指令,或者使用块来自定义respond_to调用以处理多种格式响应。

由于大多数控制器使用相当常见的自定义模式,响应者通过引入更多默认行为来提供额外的抽象级别。读取针对特定格式调用to_xml / to_json的操作,以及为成功的mutator操作提供相同和重定向的mutator操作。


有一些机会可以自定义响应者的行为方式,从微妙的调整到完全覆盖或扩展行为。

班级:# 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应处理的格式。可以定制格式以确定它们将应用于哪些操作。可以使用单独的调用指定每种格式,从而允许完全自定义每种格式的操作。

responder

班级: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

这是一个包含响应者的类属性。这可以是响应调用的任何内容,这意味着您可以使用proc / lambda或响应调用的类。另一种方法是将一个或多个模块混合到现有响应器中以重载现有方法,从而增强默认行为。

respond_with

虽然可能存在一些有趣的边缘用例,但更有可能将模块扩展或混合到默认响应器中将是更常见的模式。在任何情况下,相关的选项都是资源和选项,因为它们是从来自respond_with传递的。

实例级别::location

此处的选项是将在控制器中传递给render或redirect_to的选项,但它们仅包含在成功方案中。对于GET操作,这些将是渲染调用,对于其他操作,这将是重定向的选项。其中最有用的可能是# 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')) 选项,如果respond_with的参数不足以构建正确的URL,则可以使用该选项覆盖该重定向路径。

config/locales/en.yml

作为替代方案,responders gem不仅提供了一些模块来覆盖某些默认行为。它使用扩展默认响应程序的匿名类覆盖默认响应程序,并提供类级别方法,以便将自定义模块混合到此类中。这里最有用的是闪回响应器,它提供了一组默认闪存,默认情况下将自定义委派给I18n系统,{{1}}。

我在之前的项目中使用过的自定义响应程序的一些示例包括一个自动修饰资源的响应程序,并提供了一组默认的页面标题,其中包含一个用于轻松自定义或覆盖页面标题的界面。