跳至内容 跳至搜索

ActiveRecord – Rails 中的对象关系映射

ActiveRecord 将类连接到关系数据库表,为应用程序建立一个几乎零配置的持久层。该库提供了一个基类,当子类化时,会在新类和数据库中的现有表之间设置映射。在应用程序上下文中,这些类通常被称为模型。模型还可以连接到其他模型;这可以通过定义关联来完成。

ActiveRecord 严重依赖于命名,因为它使用类和关联名称来建立各个数据库表和外键列之间的映射。虽然这些映射可以明确定义,但建议遵循命名约定,尤其是在开始使用该库时。

您可以在ActiveRecord 基础知识指南中阅读有关 ActiveRecord 的更多信息。

一些主要功能的简要概述

  • 类和表、属性和列之间的自动映射。

    class Product < ActiveRecord::Base
    end
    

    Product 类自动映射到名为“products”的表,该表可能如下所示

    CREATE TABLE products (
      id bigint NOT NULL auto_increment,
      name varchar(255),
      PRIMARY KEY  (id)
    );
    

    这也将定义以下访问器:Product#nameProduct#name=(new_name)

    了解更多信息

  • 对象之间的关联由简单的类方法定义。

    class Firm < ActiveRecord::Base
      has_many   :clients
      has_one    :account
      belongs_to :conglomerate
    end
    

    了解更多信息

  • 值对象的聚合。

    class Account < ActiveRecord::Base
      composed_of :balance, class_name: 'Money',
                  mapping: %w(balance amount)
      composed_of :address,
                  mapping: [%w(address_street street), %w(address_city city)]
    end
    

    了解更多信息

  • 对于新对象或现有对象,验证规则可能不同。

    class Account < ActiveRecord::Base
      validates :subdomain, :name, :email_address, :password, presence: true
      validates :subdomain, uniqueness: true
      validates :terms_of_service, acceptance: true, on: :create
      validates :password, :email_address, confirmation: true, on: :create
    end
    

    了解更多信息

  • 整个生命周期(实例化、保存、销毁、验证等)可用的回调。

    class Person < ActiveRecord::Base
      before_destroy :invalidate_payment_plan
      # the `invalidate_payment_plan` method gets called just before Person#destroy
    end
    

    了解更多信息

  • 继承层次结构。

    class Company < ActiveRecord::Base; end
    class Firm < Company; end
    class Client < Company; end
    class PriorityClient < Client; end
    

    了解更多信息

  • 事务。

    # Database transaction
    Account.transaction do
      david.withdrawal(100)
      mary.deposit(100)
    end
    

    了解更多信息

  • 对列、关联和聚合的反射。

    reflection = Firm.reflect_on_association(:clients)
    reflection.klass # => Client (class)
    Firm.columns # Returns an array of column descriptors for the firms table
    

    了解更多信息

  • 通过简单的适配器进行数据库抽象。

    # connect to SQLite3
    ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'dbfile.sqlite3')
    
    # connect to MySQL with authentication
    ActiveRecord::Base.establish_connection(
      adapter:  'mysql2',
      host:     'localhost',
      username: 'me',
      password: 'secret',
      database: 'activerecord'
    )
    

    了解更多信息并阅读有关对MySQLPostgreSQLSQLite3的内置支持。

  • Log4rLogger 的日志记录支持。

    ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
    ActiveRecord::Base.logger = Log4r::Logger.new('Application Log')
    
  • 使用迁移进行与数据库无关的架构管理。

    class AddSystemSettings < ActiveRecord::Migration[7.1]
      def up
        create_table :system_settings do |t|
          t.string  :name
          t.string  :label
          t.text    :value
          t.string  :type
          t.integer :position
        end
    
        SystemSetting.create name: 'notice', label: 'Use notice?', value: 1
      end
    
      def down
        drop_table :system_settings
      end
    end
    

    了解更多信息

理念

Active Record 是对象关系映射 (ORM) 的实现,其 模式 与 Martin Fowler 描述的同名模式一致。

“一个对象,它封装数据库表或视图中的一行,封装数据库访问,并在该数据上添加领域逻辑。”

Active Record 尝试提供一个连贯的封装,作为对象关系映射不便的解决方案。此映射的主要指令是最大程度地减少构建真实世界域模型所需的代码量。这可以通过依赖一些约定来实现,这些约定使 Active Record 能够从最少的明确指令中推断出复杂的关系和结构。

约定优于配置

  • 没有 XML 文件!

  • 大量的反射和运行时扩展

  • 魔术本质上并不是一个坏词

承认数据库

  • 允许您在特殊情况下和性能方面转到 SQL

  • 不会尝试复制或替换数据定义

下载和安装

可以使用 RubyGems 安装最新版本的 Active Record

$ gem install activerecord

源代码可以作为 GitHub 上 Rails 项目的一部分下载

许可证

Active Record 根据 MIT 许可证发布

支持

API 文档位于

Ruby on Rails 项目的错误报告可以提交到这里

功能请求应在此处讨论 rails-core 邮件列表