通过上一讲,我们已经对REST on Rails的基本框架有所了解,但是它是如何实现根据客户端的请求类型来返回不同类型的资源表示的呢?这就是我们这一讲所要讲的,秘密就在于respond_to。
首先让我们来看看我们在上一讲中生成的airports控制器的代码:
class AirportsController < ApplicationController
def index
@airports = Airport.find :all
respond_to do |format|
format.html # do nothing, allow Rails to render index.rhtml
format.js # do nothing, allow Rails to render index.rjs
format.xml { render
ml => @airports.to_xml }
end
end
end
我们以index方法为例,其它方法的实现大同小异。第一行代码很容易理解,获取所有的机场信息,但是接下来的代码就比较费解了,而这也正是REST on Rails的关键所在,那个respond_to是做什么的呢?
我们知道,在HTTP协议中,客户端会在他们的HTTP首部包含一些元信息(meta-information),这些元信息按照“字段:值”的方式来组织,HTTP协议预定义了很多标准字段,其中的一个字段就是“Accept-type“,它代表发送请求的客户端能够支持或者说理解的资源表示类型,如果没有为这个键指定值,服务端会认为客户端能够理解标准的HTML文档,当然,客户端可以为这个字段指定任意的符合MIME规范的类型值,假设客户端设置这个字段为”Accept-Type: text/xml“,则服务端必须返回资源的XML表示。
所以respond_to事实上就是根据HTTP首部的Accept-Type字段来决定向客户端返回那种类型的资源表示,如果不使用respond_to,我们的实现可能会是这个样子:
class AirportsController < ApplicationController
# Pretend that Rails will call our index action,
# and will pass in the value of the Accept-Type header
def index(client_format)
@airports = Airport.find :all
if client_format == “text/html”
# TO DO: render the default template
elsif client_format == “application/javascript”
# TO DO: return some javascript
elsif client_format == “application/xml” || client_format == “text/xml”
# TO DO: return some XML back the client
# … more elsif statements here for each MIME type you want to support
end
end
end
这很丑陋,不是吗?但它却相当直观,我想respond_to的作者可能最初也是这么写的,或者这段代码至少在他的脑海中闪现过,但立刻就被他否定了,因为它实在是太蹩脚了,所以他对这段代码进行了重整,于是有了respond_to。
respond_to do |format|
format.html # do nothing, allow Rails to render index.rhtml
format.js # do nothing, allow Rails to render index.rjs
format.xml { render
ml => @airports.to_xml }
end
但是Block内的代码看起来仍然比较古怪,事实上,如果我们理解了respond_to的设计思想,那么这段代码看起来就非常理所当然了。
respond_to基于这样的思想设计的,你不需要知道客户端的请求到底是那种类型,你只需要告诉Rails你准备支持那些类型的请求,Rails会自动帮你处理剩下的事情。
所以,这里我们告诉Rails,对于HTML和JS类型的请求,采用默认的实现,而对XML则使用我们在Block内提供的实现。
指南到这里就结束了,篇幅有限,我们只能对REST的基本概念和它在Rails中的简单实现做一个基本的介绍,REST on Rails的世界还有更多的东西等着你去探索。
我建议你尝试动手创建一个Rails应用,然后试试scaffold_resource生成器,阅读并试着理解生成的代码,然后尝试修改view和controller,事实上,比你想象的要简单的多,不是吗?
祝你好运同时期待你的反馈!
分享到:
相关推荐
sinatra-respond_to 描述: 在Sinatra中提供对内置Web服务支持的response_to样式Rails块 功能/问题: 根据提供的内容处理内容类型的设置 自动可以调整XMLHttpRequests返回Javascript 根据HTTP_ACCEPT标头解析...
Ruby on Rails的respond_to代码类似物对ASP.NET MVC NuGet 项目: 说明 该库为您的控制器提供了类似响应响应的 RoR 扩展方法。 简而言之, RespondTo允许您的操作根据客户端提交的 *HTTP Accept* 标头以不同的...
我不喜欢在所有操作中编写 rails 的respond_to和/或respond_with 。 但是没有它们,如果请求具有意外的Accept:标头,应用程序会导致 ActionView::MissingTemplate。 示例:请求可能导致错误, AV::MissingTemplate ...
"线上问题分析:The target server failed to respond(目标服务器返回失败)" 知识点总结 在本文中,我们将分析一个常见的线上问题,即目标服务器返回失败(The target server failed to respond)。我们将从多个...
在使用Apache HttpClient进行HTTP通信时,可能会遇到"HttpClient问题:The server failed to respond with a valid HTTP resp"这样的异常。这个错误通常表示服务器未能返回一个有效的HTTP响应,这可能是由多种原因...
to_spreadsheet to_spreadsheet允许您的Rails 3+应用程序使用现有的slim / haml / erb / etc视图呈现Excel文件。安装将其添加到您的Gemfile中: gem 'to_spreadsheet'用法在控制器中: # my_thingies_controller....
CSV 与显示JSON或XML一样,此gem... ApplicationController respond_to :xml , :json , :csv def index respond_with Widget . all end def show respond_with Widget . find ( params [ :id ] ) endend 或者: class W
to_lang to_lang是一个Ruby库,它在Google Translate API的支持下将语言翻译方法添加到字符串和数组中。 安装 只需运行: gem install to_lang 用法 要使用to_lang ,需要使用该库,然后使用您的Google Translate ...
}respond_to :json在app / controllers /中创建一个Api控制器class ApiController < ActionController::API include ::ActionController::Serialization respond_to :jsonend将以下gem添加到j
if method_sym.to_s =~ /^find_by_(.*)$/ find($1.to_sym => arguments.first) else super end end end ``` 这段代码定义了一个`Legislator`类,并在其上实现了`method_missing`。当尝试调用形如`find_by_...
它被定义为:/// This struct represents a chatbot that is connected to a given `ship`,/// is watching/posting to a specific `chat_ship`/`chat_name`/// and is using the function `respond_to_message` to ...
<script src="path/to/respond.min.js"> ``` 2. **确保HTML文档类型声明正确**:对于IE8,确保你的文档类型声明为`<!DOCTYPE html>`. 这会触发IE8的"标准模式",这是`respond.js`工作的前提。 3. **开启X-UA-...
respond_to? ( :blank? ) 将以上内容与ActiveSupport版本进行比较: require 'active_support/core_ext/object/blank' unless Object . new . respond_to? ( :blank? ) 关键区别在于功能的即
<script src="path/to/respond.min.js"> <![endif]--> <!-- 页面内容 --> ``` 这段代码中的`<!--[if lt IE 9]>...<![endif]-->`是条件注释,只在IE8及以下版本的浏览器中执行,这样可以确保其他现代浏览器...
should "respond to: push" do assert_respond_to @queue, :push end end end ``` 这段代码定义了一个测试方法:“测试:一个队列实例应该能够响应 :push 调用”。可以看出,通过上下文的方式,测试代码不仅更...
Mobylette 2.0+ deprecated the respond_to_mobile_requests method. Now you must use `include Mobylette::RespondToMobileRequests` instead. to configure it, see the configuration. Also stylesheet and ...
典型的 Rails 控制器create操作如下所示: # POST /products # POST /products.json def create @product = Product.new(params[:product]) respond_to do |format| if @product.save format.html { redirect_to @...
format.ext_json { render :json => @post.errors.to_json, :status => :unprocessable_entity } end end end ``` #### 总结 Rails 结合 Ext JS 的方式能够极大地提高 Web 应用的开发效率。通过使用丰富的 ...
- How long will it take for the collaborator to respond? 3 Straightforward Reasons to Mock 1. Collaborator not yet implemented or still under development 2. Hardware independence 3. Fault ...
npm install --save react-respond-to 注意:该库假定您已为Array.prototype.find和matchMedia放置了必要的matchMedia 。 为什么要使用另一个响应组件? 简而言之,我们查看了可用的内容,但没有找到自己喜欢的API...