rails组合oracle时的一些命名麻烦处理

rails结合oracle时的一些命名麻烦处理
大概翻了一下书店里的一些关于Ruby on Rails的书籍,和网上的一些教材,大多都是讲述rails和MySql的的例子,并且例子中用到的表结构大部份都是使用rails默认主键名称“ID”, 并且大都遵行Rails的默认命名规则。对象用单数,表名用复数,主键默认为“id”类型为自增类型的。如果是Oracle数据库的话没有自增类型的字段,就要建间一个名称为“表名_seq”的sequence(序列)。这对于将一个现有的系统转型为Ruby无疑是太多的限制。网上关于解决这方面的中文教程却很少。因此把我的学习经验发出来与大家共享。

背景:
刚接触Ruby,想把一个现有系统的部份主要功能用Ruby实现,看Ruby是否真如它说的那样能提高程序员很高的开发效率。因此所有的操作都必须在已为的数据库结构中实现。所以就要解除rails默让规则的限制。数据库用的是oracle9i,以一个最简单的例子“系统登陆”讲述这次的学习过程。

这个功能涉及三张表:S_USER(用户表)  S_ROLE(角色表) S_USER_2_ROLES(用户与角色的关系)



create table S_ROLE
(
  ROLE_ID   VARCHAR2(10) not null,
  ROLE_NAME VARCHAR2(30),
  POPEDOMS  NCLOB,
  ROLE_BEW  VARCHAR2(20),
  ROLE_JB   VARCHAR2(1)
);
create table S_USER
(
  USER_ID        VARCHAR2(6) not null,
  USER_NAME      VARCHAR2(20),
  PASSWD         VARCHAR2(32),
  DEPARTMENT_NUM VARCHAR2(12),
  PHONE_NUM      VARCHAR2(21),
);
create table S_USER_2_ROLES
(
  USER_ID VARCHAR2(10),
  ROLE_ID VARCHAR2(10)
);

用户与角色是多对多的关系。用过rails的朋友看了以上这个表结构有很多地主都与rails的默认惯例不符,主要体现为以下内容:
1、rails默认表名都是复数的,这里面的表名都不是复数。
2、rails默认主键名称为ID,类型为自动类型。而这里面S_USER的主键为USER_ID,S_ROLE的主键为ROLE_ID并且都是字符型。
3、在多对多的关系时,保存关系的表名默认为:“表名1_表名2”,两个表名以字母的顺序排列,所以默认情况下上面这个结构的关系统表的名称应该是“S_ROLE_S_USER”,因为R的字母在U的字母前面。而我这里的表名是S_USER_2_ROLES显示也与Rails的默认惯例不符。
4、rails默认在多对多的关系时,中间表的中保存两个表的主键的字段应该为“类名的小写_id”也就是我上面的S_USER_2_ROLES应改为如下结构:



create table S_USER_2_ROLES
(
  rails中用户表的类名_ID VARCHAR2(10),
  rails中角色表的类名_ID VARCHAR2(10)
)

可是这已经是一个现有系统,暂时不可能这样改。

好了目前面对的是以上的这些总是,下面看看我们要怎么解决这些总是。首先先看看rails中有什么函数能帮我们解决这些总是。
一、解决问题1、2:参考Class  ActiveRecord::Base帮助:
它有以下函数帮我们解决这些问题
set_table_name(value = nil, &block)
用于设置对象与数据库对应的表名。

set_sequence_name(value = nil, &block)
如果是使用Oracle并且想使用类似于自动主键的功能,可以设置这个值,告诉rails用哪个序例来实现自增。

set_primary_key(value = nil, &block)
设置表的主键名称,这样可以解除rails中默认id字段为主键的限制。
以下是一个例子:
class SRole < ActiveRecord::Base
set_table_name "s_role" #设置本对象与数据表s_role对应
set_primary_key 'role_id' #设置该表的字段为role_id
end
class SUser < ActiveRecord::Base
set_table_name "s_user"
set_primary_key 'user_id'
end

一、解决问题3、4:参考Module ActiveRecord::Associations::ClassMethods帮助:
d 在处理多对多的对应关系时,我们会用到has_and_belongs_to_many(association_id, options = {}, &extension)函数。这个函数的第二个参数是一个hash表。里面的一些值可以帮助我们解除rails的默认

:class_name 用于指定与本Class关联的类的名称。
:join_table 用于指定保存对应关系统的中间表的名称。如我们上面的例子中可以指定这个键的值为s_user_2_roles,来解决问题3.
:foreign_key 用于指定中间表中用于记录本类的主键的字段的名称。
:association_foreign_key 用于指定中间表中记录关系类的主键的字段的名称。结合:foreign_key 我们可以用这个属性帮助解决上面的问题4
另外还有一些有用的键值如:
:order 指定关系类的排序方式。
:offset 指定从第几个记录开始提取
:limit 指定提取多少条记录等等.....

最后给出我们上面这个实例中的完整代码:
class SUser < ActiveRecord::Base
has_and_belongs_to_many :roles,:foreign_key=>"user_id",
  :association_foreign_key =>"role_id",:class_name=>"SRole",:join_table=>"S_USER_2_ROLES"
set_table_name "s_user"
set_primary_key 'user_id'
end

class SRole < ActiveRecord::Base
has_and_belongs_to_many :users,:foreign_key=>"role_id",
  :association_foreign_key =>"user_id",:class_name=>"SUser",:join_table=>"S_USER_2_ROLES"
set_table_name "s_role"
set_primary_key 'role_id'
end