rails 里一般有哪些 database 保留字

🕐
关于 rails 里的一些保留字约定

在 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_orderordering
  • group: 建议改为 group_name
  • user: PostgreSQL 中是保留字,MySQL 中有时也是。建议改为 accountmember
  • key: 建议改为 api_keycode
  • index: 建议改为 positionidx
  • 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. 命名最佳实践

  1. 加前缀/后缀
    • 不要用 order,用 order_datesort_order
    • 不要用 user 做表名,用 accountsmembers
    • 不要用 type,用 kind, category, roleuser_type
  2. 使用复数表名,单数字段名:遵循 Rails 默认约定。

B. 如果必须使用保留字

如果你必须使用(例如对接旧数据库),可以通过以下方式访问:

  1. 读取/写入时绕过方法查找
    使用 self[:column_name]read_attribute(:column_name) 而不是 model.column_name

    # 假设有一个字段叫 'type'
    user.type        # 危险!返回的是类名 (STI)
    user[:type]      # 安全!返回数据库里的字符串值
    user.read_attribute(:type) # 安全
    
  2. 在 Migration 中显式引用
    Rails 通常会自动处理引号,但在写原生 SQL 时需小心。

    # Rails 会自动处理为 "order"
    add_column :posts, :order, :integer
    
  3. 配置 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% 的冲突问题。