初尝
API
设计
49
HTTP
身份验证
Rails
原生支持三种身份验证方式:基本验证、摘要验证和令牌验证。
Active Support
开发者可以使用
Active Support
提供的
API
为其他开发者提供钩子。
此外,
Active Support
提供了生成器,用于快速创建模型、控制器、路由和测试桩件
stub
),还支持插件和第三方库,降低了创建应用和试验新功能的成本。
总之,即使不用视图层,
Rails
仍有很多功能值得使用。
WikiCat API
我们要设计的应用使用维基百科的分类系统,为指定的关键字生成分类树。维基百科的
分类系统是一种分类方式,也是概念级别(针对维基百科中的文章)。
维基百科的分类系统是所有用户不断编辑和归类百科条目的成果,得到的是一张分类图,
不过严格来说不是树状结构,也没有层次。但是,同一个话题可能属于多个类别,也就
是说有些分类有多个父级分类。
维基百科的分类系统可以视作一个宝藏,人们都在开发其价值,用它索引维基百科中的
文章。
这个
API
不会使用维基百科的整个数据库。我们假设已经准备好了一些数据,分类都已
经提取出来,而且相互链接好了。
有了数据,我们要将其导入应用,然后创建用于访问和操作数据的模型和控制器。
这个
API
的作用是,找出
URL
参数中指定分类的全部子分类。在接下来的几章中我们
会继续扩展这个
API
,逐渐把它开发成维基百科分类系统的
REST
式接口。
准备数据库
维基百科提供了全部内容的副本供用户使用,这些内容基于“知识共享
署名
-
相同方式
共享
3.0
协议”(
CC BY-SA
)和“
GNU
自由文档协议”(
GFDL
)发布。
维基百科的分类和分类链接已经由我准备好了,可以直接导入应用。这些数据可以到
GitHub
网站中的
WikiCat
仓库(
https://github.com/hiromipaw/wikicat
)下载。
因为英语分类链接表包含大量记录,为了便于测试,我还选摘了部分分类,这样把数据
转储导入开发数据库时就不用等待几个小时了。
50
3
维基百科使用的数据库是
MySQL
,尽管数据转储可以转换成其他
SQL
语言或
NoSQL
语言,不过这个
WikiCat API
会使用
MySQL
首先,确认操作系统中已经安装了
MySQL
。执行下述命令:
$
mysql --version
mysql Ver 14.14 Distrib 5.6.20, for osx10.9 (x86_64) using
EditLine wrapper
你的操作系统中可能没有安装
MySQL
,如果是这样,就要安装。
Mac OS X
系统的用户可以使用
brew
,方法是执行下述命令:
$
brew install mysql
Linux
系统中,可能要先安装所需的库:
$
apt-get install libmysqlclient18 libmysqlclient-dev
然后再安装
MySQL
客户端和服务器:
$
apt-get install mysql-client-5.5 mysql-server-5.5
Windows
系统中,可以使用
MySQL
安装程序。
MySQL
的文档中有安装说明(
http://
dev.mysql.com/doc/refman/5.6/en/mysql-installer.html
)。
MySQL
安装程序简化了一系列
MySQL
产品的安装和升级过程。使用它,用户可以查看
安装了哪些产品,还能根据需要配置、升级或卸载。通过安装程序还能安装插件、文档
和教程,安装程序有
GUI
和命令行接口。
确定操作系统中安装了
MySQL
,而且通过
mysql --version
命令测试可以使用,之后
要为
Rails
安装
mysql
gem
,以便
Rails
应用与数据库交互。执行下述命令:
$
gem install mysql
现在,我们要创建一个使用
MySQL
(而非
SQLite
)的
Rails
应用。我们想创建的是一个
只提供
API
的应用,因此要使用
Rails::API
。执行下述命令,安装
rails-api
$
gem install rails-api
然后,执行下述命令,生成应用:
$
rails-api new wikicat -d mysql
与之前一样,这个命令会创建一个
Rails
应用。
初尝
API
设计
51
Rails::API
https://github.com/rails-api/rails-api
)生成的应用是常规
Rails
应用的子
集,专门用于创建只提供
API
的应用。这类应用通常不需要全部
Rails
中间件。
创建应用之后,我们要初始化数据库:
$
cd wikicat
$
rake db:create
rake db:create
命令会创建开发和测试数据库。这个命令只需在创建数据库时运行一次。
接下来,我们要让应用运行指定的数据库迁移。这一步在下一节讨论。
生成模型
准备好数据库之后,可以开始编写应用逻辑了。
分类表包含下述几列:
cat_id: <Integer>,
cat_title: <String>;,
cat_pages: <Integer>,
cat_subcats: <Integer>,
cat_files: <Integer>;
各列描述一个分类的一个属性。下面按顺序说明:
cat_id
从维基百科中获取的分类
ID
cat_title
分类的标题,例如“
Sports
”或“
Science
”。
cat_pages
属于该分类的页面数量。
cat_subcats
属于该分类的子分类数量。
cat_files
属于该分类的文件数量。
52
3
下面据此生成
Category
模型:
$
rails generate model Category cat_id:integer cat_title:string\
cat_pages:integer cat_subcats:integer cat_files:integer
这个命令会生成
Category
模型和一些默认文件:
invoke active_record
create db/migrate/20140821090455_create_categories.rb
create app/models/category.rb
invoke test_unit
create test/models/category_test.rb
create test/fixtures/categories.yml
还可以把完整的命令
rails generate
简化成
r
ails g
生成的第一个文件是用于创建
categories
表的迁移文件。迁移是
Active Record
提供的功
能,作用是以一种一致且简单的方式逐渐演进数据库模式。迁移的思想是,开发者无需
使用
SQL
编写模式修改代码,而使用
Ruby
句法描述想对数据库或单个表做什么改动。
一开始,数据库模式是空的,每次运行迁移后,不断有表、列或单个记录添加到数据库中,
或者从数据库中删除。然后,
Active Record
相应地更新模式,修改
db/schema.rb
文件,
体现最新的结构。
迁移文件存储在
db/migrate
文件夹中,按创建的时间排序。文件名中有时间戳。
下面,打开我们遇到的第一个迁移文件,查看里面的内容:
# db/migrate/<timestamp>_create_categories.rb
class CreateCategories > ActiveRecord::Migration
def change
create_table :categories do |t|
t.integer :cat_id
t.string :cat_title
t.integer :cat_pages
t.integer :cat_subcats
t.integer :cat_files
t.timestamps
end
end
end
如果想在表中添加更多的列,则可以生成迁移文件。因为还没运行迁移,还可以直接修
create_categories
迁移文件。
初尝
API
设计
53
我们想把维基百科的分类
ID
当做主键,而不再生成一个
ID
字段。此外,我们还想添加
created_at
updated_at
两列。为此,我们像下面这样修改迁移文件:
# db/migrate/<timestamp>_create_categories.rb
class CreateCategories > ActiveRecord::Migration
def change
create_table :categories, {:id => false} do |t|
t.integer :cat_id
t.string :cat_title
t.integer :cat_pages
t.integer :cat_subcats
t.integer :cat_files
t.date :created_at
t.date :updated_at
t.timestamps
end
execute "ALTER TABLE categories ADD PRIMARY KEY (cat_id);"
end
end
接下来,我们要创建
Link
模型。首先,我们还是先看一下维基百科的
SQL
转储,了解
CategoryLinks
表的结构:
cl_from: <Integer>,
cl_to: <String>,
cl_sortkey: <VarBinary>,
cl_timestamp: <Date>,
cl_sortkey_prefix: <VarBinary>
cl_collation: <VarBinary>
cl_type: <String>
这些列也都各自描述分类链接的一个属性:
cl_from
链接所在页面的
ID
cl_to
目标分类的名称(没有命名空间前缀)这是分类的标题,例如
Sports
”或“
Science
”。
cl_sortkey
在分类列表中排序页面的键。对子分类来说,是分类的标题。
cl_timestamp
表中的链接是最后的更新时间。

Get RESTful Rails Development (中文版) now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.