rails 里一般有哪些 database 保留字
在 Ruby on Rails 中,所谓的“保留字”其实分为两类:一类是 Active Record (Rails 框架层面) 的方法名或属性名,另一类是 底层数据库 (SQL 层面) 的语法关键字。
如果将数据库字段(Column)或表(Table)命名为这些保留字,可能会导致查询错误、方法冲突或意想不到的行为。
以下是详细的分类列表和注意事项:
1. Active Record 保留字段名 (高风险)
这些是 Rails Active Record 对象内部使用的方法或属性。绝对不要将数据库列名命名为这些,否则会导致严重冲突。
-
id: 主键。虽然你可以强制修改,但通常不应作为普通字段。 -
type: 最常见坑。Rails 使用它来实现 单表继承 (STI)。如果你存了一个叫type的字段(比如用户类型),Rails 会尝试把它当作类名来实例化对象,导致报错。 -
attributes: 返回模型所有属性的 Hash。 -
connection: 数据库连接对象。 -
table_name: 表名。 -
errors: 验证错误对象。 -
transaction: 数据库事务方法。 -
new_record: 判断是否为新记录的方法。 -
read_only: 判断是否只读。 -
destroyed: 判断是否已销毁。 -
lock_version: 用于乐观锁(Optimistic Locking)。 -
count,size,length: 集合常用方法,作为列名访问时会有冲突。 -
parent,children: 如果在树形结构中使用,可能与某些 gem 或内部方法冲突。
2. SQL 语法保留字 (中风险)
这些是数据库(MySQL, PostgreSQL, SQLite 等)的语法关键字。
注意:现代版本的 Rails (5+) 在生成 SQL 时通常会自动给字段名加上引号(如 "order"),所以很多 SQL 保留字在 Rails 里其实是可以用的,但为了可移植性和可读性,建议避免。
常见的 SQL 保留字包括:
-
order: 非常常用,建议改为sort_order或ordering。 -
group: 建议改为group_name。 -
user: PostgreSQL 中是保留字,MySQL 中有时也是。建议改为account或member。 -
key: 建议改为api_key或code。 -
index: 建议改为position或idx。 -
desc: (Description 的缩写常与此冲突)。 -
select,from,where,limit,offset,join,table,column,view,trigger.
3. Rails 魔法
列 (约定俗成)
这些不是严格意义上的保留字,但 Rails 对它们有特殊处理(自动管理时间戳等)。如果你手动定义它们,可能会覆盖 Rails 的默认行为。
-
created_at: 记录创建时间。 -
updated_at: 记录更新时间。 -
created_on,updated_on: 旧版 Rails 或特定配置下的日期。 -
lock_version: 启用乐观锁时必须存在。 -
type: 再次强调,用于 STI。 -
_id后缀: 外键约定(如user_id)。虽然可以用,但如果你有一个字段叫name_id,Rails 可能会误以为它是外键关联。
4. 如何避免和解决?
A. 命名最佳实践
- 加前缀/后缀:
- 不要用
order,用order_date或sort_order。 - 不要用
user做表名,用accounts或members。 - 不要用
type,用kind,category,role或user_type。
- 不要用
- 使用复数表名,单数字段名:遵循 Rails 默认约定。
B. 如果必须使用保留字
如果你必须使用(例如对接旧数据库),可以通过以下方式访问:
读取/写入时绕过方法查找:
使用self[:column_name]或read_attribute(:column_name)而不是model.column_name。# 假设有一个字段叫 'type' user.type # 危险!返回的是类名 (STI) user[:type] # 安全!返回数据库里的字符串值 user.read_attribute(:type) # 安全在 Migration 中显式引用:
Rails 通常会自动处理引号,但在写原生 SQL 时需小心。# Rails 会自动处理为 "order" add_column :posts, :order, :integer配置 ActiveRecord 忽略 STI:
如果你必须用type字段且不需要 STI 功能:class MyModel < ApplicationRecord self.inheritance_column = :_type_disabled # 禁用 STI 查找 end
总结建议清单
在创建 Migration 时,尽量避免使用以下名称作为列名:
| 类别 | 推荐避免的名称 | 推荐替代方案 |
|---|---|---|
| Rails 核心 | type, id, attributes, errors |
kind, uuid, props, validation_errors |
| SQL 关键字 | order, group, user, key, index |
sort_order, group_name, member, api_key, position |
| 时间戳 | created_at, updated_at |
(除非你确实想覆盖默认行为) |
| 外键约定 | xxx_id (非外键时) |
xxx_code, xxx_num |
一句话原则:如果不确定,就在字段名后面加一个具体的名词后缀(如 _value, _date, _name),这通常能解决 99% 的冲突问题。