- 浏览: 137646 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (140)
- ruby on rails (23)
- 随笔 (1)
- 部署 (3)
- ubuntu源 (2)
- linux (28)
- web (9)
- IT (3)
- linux,数据库 (3)
- MOOC (4)
- ubuntu (20)
- win7 (2)
- git (6)
- github (2)
- ubuntu,python (1)
- java,JDK (1)
- ubuntu,qq (1)
- vagrant (3)
- virtualbox (2)
- sass (1)
- centos (3)
- Sublime (1)
- nginx (4)
- passenger (1)
- VPN (0)
- mysql (4)
- VIM (1)
- bbb (1)
- 编码设置 (2)
- mongo (4)
- edx (2)
- ssh (1)
- python (1)
- phpmyadmin (1)
- libreoffice (2)
- docker (4)
- pg (1)
- PostgreSQL (2)
- 系统时间设置 (1)
- ansible (1)
- Sinatra (1)
- 硬盘挂载 (1)
- npm (1)
- smtp (1)
- docker 镜像 (1)
- Memcached (1)
最新评论
前言
在许多Web应用中都需要预览文档的功能。而用户可能用不同的设备访问Web应用,可能是装有Windows系统的PC台式机,也有可能是iOS系统的iPad。一般来说,要预览的文档通常是主流的Office文档,包括.doc、.ppt、.docx、.pptx文档,也包括Adobe的.pdf文档。
因此开发一个能够在不同客户端上使用的,支持主流Office文档类型的在线文档预览系统就显得非常重要。
目标
实现基于Web的跨平台的在线预览功能,支持主流Office文档。另外我们的服务器是Linux系统,不能够安装Microsoft Office软件。
我的解决方案
先大致地说一下我是如何实现的。为了实现这个功能,我用了下面的组件:
PDF.js
OpenOffice
PyODConverter
PDF.js 是Mozilla实验室开发的关于HTML5技术的一个开源项目,用于在网页上显示PDF文档,而不需要任何浏览器插件等原生代码。目前这个开源项目放在了GitHub上,网址是https://github.com/andreasgal/pdf.js
演示地址:http://mozilla.github.io/pdf.js/web/viewer.html
OpenOffice是Apache开源软件基金会开发的一款开源软件,是可以在Linux上运行的Office软件。OpenOffice可以打开主流的Microsoft Office的各种文档,例如.doc,.docx,.ppt,.pptx格式的文档。OpenOffice有一个文档转换服务,这个服务是以网络服务的形式运行的。启动这个服务,我就可以在任何类型的代码中通过端口调用这个服务。
PyODConverter是一个Python脚本,用于自动化的文档格式转换,依赖于LibreOffice or OpenOffice。我用它把Office文档转成PDF文档。
PyODConverter代码托管在 https://github.com/jamayka/barberry-plugin-openoffice/tree/master/externals/pyodconverter 上。
实现过程
整个实现分为**“Office文档转PDF”**和**“PDF文档在Web端显示”**两部分。
,后端负责将各种Office文档通过OpenOffice服务转换成PDF文档,而前端通过pdf.js显示PDF的内容。由于是采用了pdf.js显示PDF文档,浏览器端不需要安装任何插件,但是需要支持部分HTML5的功能特性。因此旧浏览器例如IE8,IE7,IE6就不能够使用pdf.js了.
Office文档转PDF
我利用了OpenOffice服务将各种Office文档转换成了PDF文档。写的脚本是*rake task*脚本,这样我可以用*rake*命令运行此脚本。这个脚本作为一个守护进程运行,它不断地检查系统里是否有新的上传文件。如果有新上传的文件,则启动转换过程,步骤如下:
启动OpenOffice的服务
检查是否有新的Office文档上传
调用PyODConverter转换文档
更新Model上的字段,指向生成的用于预览的PDF
重复步骤2到4
整个rake task脚本的代码如下:
# -*- encoding : utf-8 -*-
PYTHON_PATH = '/opt/openoffice4/program/python'
CONVERTER_PATH = File.expand_path('../DocumentConverter.py', __FILE__)
def gen_preview(beDaemon = false)
begin
no_preview_materials = CoursewareMaterial.where(preview_file_name: nil).where(['doc', 'docx', 'ppt', 'pptx'].map {|x| "upload_file_name LIKE '%.#{x}'"}.join(' or '))
if no_preview_materials.size > 0
puts "Prepare to process #{no_preview_materials.size} items."
no_preview_materials.each do |material|
begin
generate_preview material
rescue
puts "[Exception] #{$!}".red
end
end
end
break if not beDaemon
sleep 30
end while true
end
def generate_preview material
puts "Generating preview PDF for [#{material.upload_file_name}]..."
if material.upload.path.to_s =~ /\.(doc|docx|ppt|pptx|pdf)$/
tmpPdfPath = File.join(Dir.tmpdir, File.basename(material.upload.path, '.*') + '.pdf')
# try to delete existing temporary file if it exists.
begin
File.delete tmpPdfPath
rescue
# do nothing
end
# relaunch openoffice if it quit.
if `pgrep soffice`.size == 0
puts 'Relaunch OpenOffice service.'
spawn 'soffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -norestore -nofirststartwizard -nologo -headless &'
end
out = nil
cmd = "#{PYTHON_PATH} #{CONVERTER_PATH} '#{material.upload.path}' '#{tmpPdfPath}'"
puts "Execute command: \n#{cmd}"
out = `#{cmd}`
if File.exists?(tmpPdfPath)
material.preview = File.open(tmpPdfPath, 'rb')
material.save
File.delete tmpPdfPath
puts "Preview PDF for [#{material.upload_file_name}] is generated.".green
else
puts "An error occured when invoke DocumentConverter.py. #{out}".red
end
else
puts "The material [#{material.upload_file_name}] is not available for generating preview PDF.".yellow
end
end
PDF文档在Web端显示
首先在asset pipeline中添加pdf.js,这一步可以通过引入*pdfjs-rails*这个Gem实现。然后在页面中引用需要的js和css资源即可,而这些资源包含在*pdfjs-rails*中。
Gem pdfjs-rails代码托管在https://github.com/concordia-publishing-house/pdfjs-rails中。
然后在view上添加前端代码。我用的是ERB,因此对应的文件是preview.html.erb。此文件中的代码如下所示:
<%= javascript_include_tag "compatibility" %>
<%= javascript_include_tag "l10n" %>
<%= javascript_include_tag "pdf" %>
<%= javascript_include_tag "pdfviewer" %>
<%= stylesheet_link_tag"viewer", :media => "all" %>
......
<div>
<% if not (pdf_url.nil? or pdf_url.empty?) %>
<b>内容预览:</b>
<%= pdf_viewer pdf_url %>
<% end %>
</div>
......
如以上代码所示,*pdfjs_rails*提供了用于自动生成HTML的*pdf_viewer*方法,简化了代码。当要显示一个文档时,还需要判断这个文档对应的PDF文档有没有生成,因此需要一个类似于if pdf_url.nil?的代码。为了简单起见,我就直接把此代码写在view上了。
安装部署
安装OpenOffice到Linux CentOS
这里有详细说明 http://www.if-not-true-then-false.com/2010/install-openoffice-org-on-fedora-centos-red-hat-rhel/
以作为后台服务的方式运行OpenOffice
这里有详细说明 http://stackoverflow.com/questions/11591643/failed-to-connect-to-openoffice-headless-mode
下载PyODConverter脚本
从 https://github.com/concordia-publishing-house/pdfjs-rails 下载PyODConverter脚本,放在lib/tasks/prevew目录下面,然后我把它直接上传到我的代码库里。
演示
其它几种方案
我在方案选型的过程中研究了好几种方案,但是除了上面所描述的方案之外的其他所有方案都因为各种原因而不能满足要求。下面一一列举这些未选中的方案,以及解释为何它们满足不了要求。
FlexPaper
FlexPaper 是一个商业软件,但是有采用GPLv3开源协议的免费版。然而,它仅支持ASP.NET、PHP和Java,而且部署相对复杂。我的系统是基于Linux的,开发技术是Ruby on Rails,因此不太容易和它整合在一起。
Accusoft Document Viewers
Accusoft Document Viewers 是一个商业软件,有一些很酷的Demos,下面列举两个Demo的网址。
http://prizmdemos.accusoft.com/flash.php
http://prizmdemos.accusoft.com/html5.php
可是这个软件的价格太高,而且不是提供一个组件,而是提供一套解决方案,对于我们的目标来说,这些解决方案太“重”了。
Google的文档预览服务
Google的文档预览服务(Google Docs Viewer) 真心很不错,这里有个应用实例,但是最大的问题是经常被墙,无法稳定地工作。
CUPS-PDF
根据一个StackOverflow上的解答,有一个叫CUPS-PDF的软件可以安装在Linux系列(包括Mac OS X)的操作系统上。该软件能够为系统添加一个PDF打印机。它是另一种文档转PDF的方法,通过安装PDF打印机将文档“打印”成PDF文档。用OpenOffice的命令行工具可以打印一个文档,并指定要使用的打印机。只要指定使用CUPS-PDF的打印机,就能够输出一个PDF文件到文件系统中的一个位置上。
这种方法可以很精确地将文档转换成PDF文档,可以说是“所打印即所得”
原文:
在许多Web应用中都需要预览文档的功能。而用户可能用不同的设备访问Web应用,可能是装有Windows系统的PC台式机,也有可能是iOS系统的iPad。一般来说,要预览的文档通常是主流的Office文档,包括.doc、.ppt、.docx、.pptx文档,也包括Adobe的.pdf文档。
因此开发一个能够在不同客户端上使用的,支持主流Office文档类型的在线文档预览系统就显得非常重要。
目标
实现基于Web的跨平台的在线预览功能,支持主流Office文档。另外我们的服务器是Linux系统,不能够安装Microsoft Office软件。
我的解决方案
先大致地说一下我是如何实现的。为了实现这个功能,我用了下面的组件:
PDF.js
OpenOffice
PyODConverter
PDF.js 是Mozilla实验室开发的关于HTML5技术的一个开源项目,用于在网页上显示PDF文档,而不需要任何浏览器插件等原生代码。目前这个开源项目放在了GitHub上,网址是https://github.com/andreasgal/pdf.js
演示地址:http://mozilla.github.io/pdf.js/web/viewer.html
OpenOffice是Apache开源软件基金会开发的一款开源软件,是可以在Linux上运行的Office软件。OpenOffice可以打开主流的Microsoft Office的各种文档,例如.doc,.docx,.ppt,.pptx格式的文档。OpenOffice有一个文档转换服务,这个服务是以网络服务的形式运行的。启动这个服务,我就可以在任何类型的代码中通过端口调用这个服务。
PyODConverter是一个Python脚本,用于自动化的文档格式转换,依赖于LibreOffice or OpenOffice。我用它把Office文档转成PDF文档。
PyODConverter代码托管在 https://github.com/jamayka/barberry-plugin-openoffice/tree/master/externals/pyodconverter 上。
实现过程
整个实现分为**“Office文档转PDF”**和**“PDF文档在Web端显示”**两部分。
,后端负责将各种Office文档通过OpenOffice服务转换成PDF文档,而前端通过pdf.js显示PDF的内容。由于是采用了pdf.js显示PDF文档,浏览器端不需要安装任何插件,但是需要支持部分HTML5的功能特性。因此旧浏览器例如IE8,IE7,IE6就不能够使用pdf.js了.
Office文档转PDF
我利用了OpenOffice服务将各种Office文档转换成了PDF文档。写的脚本是*rake task*脚本,这样我可以用*rake*命令运行此脚本。这个脚本作为一个守护进程运行,它不断地检查系统里是否有新的上传文件。如果有新上传的文件,则启动转换过程,步骤如下:
启动OpenOffice的服务
检查是否有新的Office文档上传
调用PyODConverter转换文档
更新Model上的字段,指向生成的用于预览的PDF
重复步骤2到4
整个rake task脚本的代码如下:
# -*- encoding : utf-8 -*-
PYTHON_PATH = '/opt/openoffice4/program/python'
CONVERTER_PATH = File.expand_path('../DocumentConverter.py', __FILE__)
def gen_preview(beDaemon = false)
begin
no_preview_materials = CoursewareMaterial.where(preview_file_name: nil).where(['doc', 'docx', 'ppt', 'pptx'].map {|x| "upload_file_name LIKE '%.#{x}'"}.join(' or '))
if no_preview_materials.size > 0
puts "Prepare to process #{no_preview_materials.size} items."
no_preview_materials.each do |material|
begin
generate_preview material
rescue
puts "[Exception] #{$!}".red
end
end
end
break if not beDaemon
sleep 30
end while true
end
def generate_preview material
puts "Generating preview PDF for [#{material.upload_file_name}]..."
if material.upload.path.to_s =~ /\.(doc|docx|ppt|pptx|pdf)$/
tmpPdfPath = File.join(Dir.tmpdir, File.basename(material.upload.path, '.*') + '.pdf')
# try to delete existing temporary file if it exists.
begin
File.delete tmpPdfPath
rescue
# do nothing
end
# relaunch openoffice if it quit.
if `pgrep soffice`.size == 0
puts 'Relaunch OpenOffice service.'
spawn 'soffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -norestore -nofirststartwizard -nologo -headless &'
end
out = nil
cmd = "#{PYTHON_PATH} #{CONVERTER_PATH} '#{material.upload.path}' '#{tmpPdfPath}'"
puts "Execute command: \n#{cmd}"
out = `#{cmd}`
if File.exists?(tmpPdfPath)
material.preview = File.open(tmpPdfPath, 'rb')
material.save
File.delete tmpPdfPath
puts "Preview PDF for [#{material.upload_file_name}] is generated.".green
else
puts "An error occured when invoke DocumentConverter.py. #{out}".red
end
else
puts "The material [#{material.upload_file_name}] is not available for generating preview PDF.".yellow
end
end
PDF文档在Web端显示
首先在asset pipeline中添加pdf.js,这一步可以通过引入*pdfjs-rails*这个Gem实现。然后在页面中引用需要的js和css资源即可,而这些资源包含在*pdfjs-rails*中。
Gem pdfjs-rails代码托管在https://github.com/concordia-publishing-house/pdfjs-rails中。
然后在view上添加前端代码。我用的是ERB,因此对应的文件是preview.html.erb。此文件中的代码如下所示:
<%= javascript_include_tag "compatibility" %>
<%= javascript_include_tag "l10n" %>
<%= javascript_include_tag "pdf" %>
<%= javascript_include_tag "pdfviewer" %>
<%= stylesheet_link_tag"viewer", :media => "all" %>
......
<div>
<% if not (pdf_url.nil? or pdf_url.empty?) %>
<b>内容预览:</b>
<%= pdf_viewer pdf_url %>
<% end %>
</div>
......
如以上代码所示,*pdfjs_rails*提供了用于自动生成HTML的*pdf_viewer*方法,简化了代码。当要显示一个文档时,还需要判断这个文档对应的PDF文档有没有生成,因此需要一个类似于if pdf_url.nil?的代码。为了简单起见,我就直接把此代码写在view上了。
安装部署
安装OpenOffice到Linux CentOS
这里有详细说明 http://www.if-not-true-then-false.com/2010/install-openoffice-org-on-fedora-centos-red-hat-rhel/
以作为后台服务的方式运行OpenOffice
这里有详细说明 http://stackoverflow.com/questions/11591643/failed-to-connect-to-openoffice-headless-mode
下载PyODConverter脚本
从 https://github.com/concordia-publishing-house/pdfjs-rails 下载PyODConverter脚本,放在lib/tasks/prevew目录下面,然后我把它直接上传到我的代码库里。
演示
其它几种方案
我在方案选型的过程中研究了好几种方案,但是除了上面所描述的方案之外的其他所有方案都因为各种原因而不能满足要求。下面一一列举这些未选中的方案,以及解释为何它们满足不了要求。
FlexPaper
FlexPaper 是一个商业软件,但是有采用GPLv3开源协议的免费版。然而,它仅支持ASP.NET、PHP和Java,而且部署相对复杂。我的系统是基于Linux的,开发技术是Ruby on Rails,因此不太容易和它整合在一起。
Accusoft Document Viewers
Accusoft Document Viewers 是一个商业软件,有一些很酷的Demos,下面列举两个Demo的网址。
http://prizmdemos.accusoft.com/flash.php
http://prizmdemos.accusoft.com/html5.php
可是这个软件的价格太高,而且不是提供一个组件,而是提供一套解决方案,对于我们的目标来说,这些解决方案太“重”了。
Google的文档预览服务
Google的文档预览服务(Google Docs Viewer) 真心很不错,这里有个应用实例,但是最大的问题是经常被墙,无法稳定地工作。
CUPS-PDF
根据一个StackOverflow上的解答,有一个叫CUPS-PDF的软件可以安装在Linux系列(包括Mac OS X)的操作系统上。该软件能够为系统添加一个PDF打印机。它是另一种文档转PDF的方法,通过安装PDF打印机将文档“打印”成PDF文档。用OpenOffice的命令行工具可以打印一个文档,并指定要使用的打印机。只要指定使用CUPS-PDF的打印机,就能够输出一个PDF文件到文件系统中的一个位置上。
这种方法可以很精确地将文档转换成PDF文档,可以说是“所打印即所得”
原文:
发表评论
-
ruby 回复功能
2015-03-24 21:44 644http://www.sitepoint.com/realti ... -
测试驱动开发(TDD)
2015-03-02 17:00 659测试驱动开发的基本过程如下: 1) 明确当前要完成的功能。可 ... -
详解rails命令行
2015-02-02 14:32 906http://blog.58share.com/?cat=7 ... -
Ruby is Big in China
2014-08-12 15:35 548http://stylesror.github.io/#rub ... -
ruby http get post
2014-07-31 11:22 767uri = URI('url') Net::H ... -
使用者認證
2014-07-29 11:18 427转自: http://ihower.tw/rails3/aut ... -
bundle exec rake i18n:check
2014-07-03 11:45 525bundle exec rake i18n:check -
ruby on rails+nginx+passenger+ubuntu
2014-06-06 00:19 861ruby 使用rvm安装 在使用rmv安装的ruby时候必 ... -
`gem install nokogiri -v '1.5.6' 报错
2014-05-18 13:07 599libxml2 is missing. please vis ... -
卸载指定版本 bundle
2014-05-05 18:04 2697gem uninstall bundler -v=1.6.2 ... -
使用Vagrant在Windows下部署开发环境
2014-03-06 10:34 698http://blog.smdcn.net/article/1 ... -
安装rails时的一个小注意
2013-12-17 10:08 859在ubuntu上安装ROR环境时候,我总是忘记一件事情,就是设 ... -
GitHub使用指南!(ubuntu)
2013-12-06 00:03 1077<!-- @page { margin: 2cm } P ... -
关于在win7上安装Ruby On Rails 环境的几点注意
2013-12-05 18:31 1480在window下安装Ruby On Rails 环境须知: 1 ... -
Ubuntu安装Ruby On Rails多版本
2013-11-29 23:44 881写Ruby程序的时候,可能 ... -
ruby数组基本操作
2013-11-08 14:52 718#创建数组的几种方法#字面量创建的方法 a = [1,2,3 ... -
Rails2.2新特性:本地化与国际化(2008-12-15 14:21:41)
2013-11-01 11:05 840http://fsjoy.blog.51cto.com/318 ... -
浅析Ruby on Rails部署方案
2013-09-27 15:16 754http://blog.csdn.net/jrckkyy/ar ... -
【转载】我是如何让Ruby项目速度提升10倍的?
2013-09-06 13:18 667作者详细描述了他是如 ... -
How to install Ruby on Rails in Ubuntu 12.04 LTS
2013-08-27 11:10 638http://blog.sudobits.com/2012/0 ...
相关推荐
《Ruby on Rails Tutorial》中文版(原书第2版,涵盖 Rails 4) Ruby 是一门很美的计算机语言,其设计原则就是“让编程人员快乐”。David Heinemeier Hansson 就是看重了这一点,才在开发 Rails 框架时选择了 Ruby...
引用自Nathan Torkington的话:“使用Ruby on Rails就像观看功夫电影一样,看似弱小的新手框架却能够用各种创造性的方式打败众多强大的对手。”这句话生动地描述了Ruby on Rails的独特之处以及它在Web开发领域的影响...
Ruby on Rails是一款基于Ruby语言的开源Web开发框架,它遵循MVC(模型-视图-控制器)架构模式,简化了Web应用的开发流程。在Linux环境下安装Ruby on Rails需要一系列的依赖包和步骤,本资源包提供了所需的所有组件,...
Ruby on Rails,简称Rails,是基于Ruby编程语言的一个开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在提高开发效率和代码的可读性。Rails以其“约定优于配置”(Convention over Configuration)...
Ruby on Rails(简称Rails)是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构...这个系统需要综合运用Ruby on Rails的各种特性和最佳实践,以提供稳定、高效、易用的在线考试服务。
Ruby on Rails,简称Rails,是基于Ruby语言的一个开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本压缩包中的"Ruby on Rails入门经典代码"提供了新手学习...
### Ruby on Rails Guides v2 - Ruby on Rails 4.2.5 #### 一、重要概念及基础假设 - **重要概念**:本指南旨在帮助读者深入理解Ruby on Rails(以下简称Rails)4.2.5版本的核心功能与最佳实践。 - **基础假设**:...
《Ruby on Rails 3 Tutorial》是一本专门为初学者设计的指南,旨在帮助读者快速掌握Ruby on Rails这一强大的Web开发框架。Ruby on Rails(简称Rails)是基于Ruby语言的一个开源框架,它采用MVC(Model-View-...
Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,极大地简化了Web应用的开发过程。Rails的哲学是“约定优于配置”,鼓励开发者遵循一套标准的...
《Ruby on Rails for Dummies》这本书将引导读者从安装Ruby和Rails环境开始,逐步学习如何创建模型、视图和控制器(MVC架构),搭建数据库,使用路由系统,以及实现CRUD(Create, Read, Update, Delete)操作。...
Ruby on Rails,简称Rails,是由David Heinemeier Hansson基于Ruby语言开发的一个开源Web应用程序框架。这个框架遵循“约定优于配置”(Convention over Configuration)的原则,致力于简化Web应用的开发流程,提高...
Ruby on Rails(简称Rails)是一种基于Ruby编程语言的开源Web应用程序框架,专为敏捷开发而设计,强调简洁的代码和“约定优于配置”的原则。它主要用于构建数据驱动的Web应用,借助于MVC(Model-View-Controller)...
Ruby on Rails,简称Rails,是一款基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-Controller)架构模式,旨在提升开发效率和代码的可读性。Rails以其“约定优于配置”的设计理念,以及“DRY(Don't Repeat ...
本中文教材《Ruby On Rails》可能是针对初学者和有一定编程基础的开发者设计的,通过PDF格式提供,便于读者在线阅读或离线保存。PDF文档通常包含详细的教程、实例代码和可能的练习题,旨在帮助学习者全面了解和掌握...
《Ruby on Rails入门权威经典》是一本专门为初学者设计的指南,旨在帮助读者全面掌握Ruby on Rails这一强大的Web开发框架。Ruby on Rails(简称Rails)是基于Ruby编程语言的开源框架,以其“DRY(Don't Repeat ...
Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用框架,它遵循敏捷开发原则,致力于简化Web开发过程。Rails的核心理念是“Convention over Configuration”(约定优于配置),这意味着开发者可以减少大量...
Ruby on Rails,简称Rails,是基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-Controller)架构模式,旨在使开发过程更加简洁高效。这个“ruby on rails 教程源码”很可能是为了辅助学习者深入理解Rails的...
Ruby On Rails 框架自它提出之日起就受到广泛关注,在“不要重复自己”,“约定优于配置”等思想的指导下,Rails 带给 Web 开发者的是极高的开发效率。 ActiveRecord 的灵活让你再也不用配置繁琐的 Hibernate 即可...
Ruby on Rails,简称Rails,是一种基于Ruby编程语言的开源Web应用程序框架,以其“Convention over Configuration”(约定优于配置)和“Don't Repeat Yourself”(DRY,不要重复自己)的原则著称。Rails使得开发Web...