web开发的主要目标还是要和数据库结合,下面来研究一下数据库的应用。为了节省时间,继续使用上一篇文章建立的test应用
一、建立mysql数据库
mysql数据库的安装和使用这里就不详细介绍了,在mysql里面建立一个testdb数据库,新建一个user表
create table users
(
id smallint(5) unsigned not null auto_increment,
created_on timestamp(14) not null,
updated_on timestamp(14) not null,
user_name varchar(20) not null,
age int not null,
constraint pk_users primary key (id)
);
二、几个重要的说明:
因为rails使用约定来代替复杂的配置,这是它开发效率高的一个重要原因,这些约定包括:
1、数据表的名称是英文复数形式的,例如users
2、必须包含一个名称为id的自增字段
建议严格按照这两个约定来建立数据表,不然会带来一些问题。(虽然通过一些配置也可以避开这两个约定,但是那样就失去了rails的简洁特色了)
另外created_on和updated_on这两个字段rails也会自己处理,但这两个字段不是必须的
三、配置数据库联接
rails安装的时候自带了mysql驱动,所以不用另外安装了。
打开D:/ROR/test/config/database.yml文件,把development一段修改为你的数据库地址、数据库名,用户名、密码
development:
adapter: mysql
database: testdb
username: root
password:
host: localhost
修改好了以后,就可以启动test应用了
四、产生model和controler
分别用ruby script/generate model user和ruby script/generate controller user来产生model和controller,屏幕显示如下:
D:/ROR/test>ruby script/generate model user
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/user.rb
create test/unit/user_test.rb
create test/fixtures/users.yml
create db/migrate
create db/migrate/001_create_users.rb
D:/ROR/test>ruby script/generate controller user
exists app/controllers/
exists app/helpers/
create app/views/user
exists test/functional/
create app/controllers/user_controller.rb
create test/functional/user_controller_test.rb
create app/helpers/user_helper.rb
注意这里的user用的是单数,这也是rails的约定之一
然后修改D:/ROR/test/app/controllers/user_controller.rb为
class UserController < ApplicationController
model :user
scaffold :user
end
然后在IE地址栏输入http://127.0.0.1:3000/user就可以看到画面了,画面上有一个New user链接,点击可以进入新增user的画面,新建一笔资料之后,back到list画面,可以看到刚才新建的记录被显示在那里,而且还多了view,edit,destroy三个链接。
到目前为止,我们没有写一行程序,rails已经帮我们建立了一个简单的应用,rails的神奇之处就在于此吧。
我们去修改一下users表的结构,可以发现rails不用做任何修改,依然是可以正常运行的。
五、rails的程序开发
上面的例子所有的工作都是rails做了,但是只是一些简单的页面,距离真正的应用还有一段距离,所以我们需要对rails的工作进行进一步的开发,这个时候我们就需要让rails生成显式的代码,以便我们进一步研究和开发。使用的命令是ruby script/generate scaffold user,屏幕显示如下:
D:/ROR/test>ruby script/generate scaffold user
exists app/controllers/
exists app/helpers/
create app/views/users
exists app/views/layouts/
exists test/functional/
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
identical app/models/user.rb
identical test/unit/user_test.rb
identical test/fixtures/users.yml
create app/views/users/_form.rhtml
create app/views/users/list.rhtml
create app/views/users/show.rhtml
create app/views/users/new.rhtml
create app/views/users/edit.rhtml
create app/controllers/users_controller.rb
create test/functional/users_controller_test.rb
create app/helpers/users_helper.rb
create app/views/layouts/users.rhtml
create public/stylesheets/scaffold.css
注意这个命令使用的仍然是user的单数形式,但是rails生成的目录却是users复数形式了。
然后在IE地址栏输入http://127.0.0.1:3000/users就可以看到画面了,注意这次我们使用的也是users复数形式。
有兴趣的话可以打开users_controller.rb和上面产生的user_controller.rb进行比较,发现他们有了比较大的差别。
另外在app/view/users目录里面有一些rhtml文件,例如edit,list,view,show,这些就是我们需要的显式程序了,你可以根据需要修改他们了。
六、关于约定的问题
我一开始尝试的时候没有注意rails对数据库建立的约定,走了一些弯路,所以我把它们写在这篇文章的开头了,以免大家重蹈我的覆辙,这里再补充说明一下不遵守这些约定带来的问题。
1、数据表名不是复数,例如
create table first
(
id smallint(5) unsigned not null auto_increment,
created_on timestamp(14) not null,
updated_on timestamp(14) not null,
user_name varchar(20) not null,
age int not null,
constraint pk_first primary key (id)
);
在generate model first和generate controller first的时候没有问题,一样要修改first_controller.rb文件,
但是IE地址栏输入http://127.0.0.1:3000/first会看到
ActiveRecord::StatementInvalid in FirstController#index
Mysql::Error: #42S02Table 'testdb.firsts' doesn't exist: SHOW FIELDS FROM firsts
解决的方法是通过改变rails的配置来取消默认的单复数转换约定
在environment.rb中使用ActiveRecord::Base.pluralize_table_names = false参数
重新启动server就可以了。
2.数据表名和model的名称不一致
例如我们建立一个employee的model和controller,但是它对应的数据表是users
先建立model和controller,画面显示如下:
D:/ROR/test>ruby script/generate model employee
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/employee.rb
create test/unit/employee_test.rb
create test/fixtures/employees.yml
exists db/migrate
create db/migrate/005_create_employees.rb
D:/ROR/test>ruby script/generate controller employee
exists app/controllers/
exists app/helpers/
create app/views/employee
exists test/functional/
create app/controllers/employee_controller.rb
create test/functional/employee_controller_test.rb
create app/helpers/employee_helper.rb
然后修改app/models/employee.rb为:
class Employee < ActiveRecord::Base
set_table_name "users"
end
记得还是要修改app/controllers/employee_controller.rb为
class EmployeeController < ApplicationController
model :employee
scaffold :employee
end
这样在IE地址栏输入http://127.0.0.1:3000/employee就会看到页面了。
3.没有id字段
如果没有id字段,那么list和new页面没有问题,但是view,edit,destroy会找不到记录,显示错误
ActiveRecord::RecordNotFound in UserController#show
Couldn't find User without an ID
4.id字段不是自增字段
list, view, edit destroy没有问题,但是新增第二条记录的时候会显示主键重复
ActiveRecord::StatementInvalid in UserController#create
Mysql::Error: #23000Duplicate entry '0' for key 'PRIMARY':
七、数据库中文乱码问题
上面的例子如果输入中文会出现乱码,解决方法是修改database.yml文件,增加一行 encoding: utf8,例如:
development:
adapter: mysql
database: testdb
encoding: utf8
username: root
password:
host: localhost
这样就OK了。
补充说明一下,我的mysql服务器的字符集是gbk,如何设置mysql的字符集就不在这里讨论了。