天天看点

Ruby on Rails研究之三:Mysql数据库开发

  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的字符集就不在这里讨论了。