[Ruby] ActiveRecord — Ruby ORM 的實現

ORM

ORM(Object Relational Mapping) 物件 — 關係對映層。

大多數的情況下,業務邏輯會使用一種物件導向的語言撰寫,如 Java、C++ 或 Ruby等。業務邏輯所使用的語言和資料本身的關聯式資料庫語言之間存在溝通的障礙。因此,人們在業務層和資料庫層之間引用了一個額外的ORM層來解決此問題。除此之外,ORM也解決了對資料庫結構修改的追蹤問題,ORM會記錄資料庫結構的歷史版本。

ActiveRecord

ActiveRecord原本是Rails 架構的元件,後來被獨立出來,作爲一個通用的ORM層實現來使用。它提供了許多對開發人員人性化的界面,隱藏了資料庫間的差異。ActiveRecord支援了很多資料庫系統,如 MySQL,sqlite,postgres,SQL Server, Oracle等。

ActiveRecord 實作

步驟1: 安裝 bundler $ gem install bundler

步驟2: 建立Gemfile,加入 gem ‘activerecord’ 後 $ bundle install

# Gemfile
source 'https://rubygems.org'
gem 'activerecord'

步驟3:手動建立移轉指令檔(Migration)

檔案的名字需要以時間戳記開頭,例如:20170501141930_create_products.rb。檔案將建立一個名爲products的資料表,除了預設的id及timestamps外,還有name、price和detail三個欄位。

# 20170501141930_create_products.rb
class CreateProducts < ActiveRecord::Migration[4.2]
def
change
create_table :products do |t|
t.string :name
t.integer :price
t.text :detail
      t.timestamps
end
end
end

步驟4: 定義Model

建立 product.rb 檔案:

# product.rb
require 'active_record'
class Product < ActiveRecord::Base
end

步驟5: 在Gemfile中加入資料庫系統 gem 'sqlite3' ,再次執行 bundle install

步驟6: 建立資料庫連線,進入 irb 環境 $ irb 後輸入下面粗體的指令:

# 載入product檔案
irb(main):002:0> require './product'
=> true
# 建立資料庫連線
irb(main):003:0> ActiveRecord::Base.establish_connection(
irb(main):004:1* adapter: 'sqlite3',
irb(main):005:1* database: 'development.sqlite3'
irb(main):006:1> )
# 執行資料移轉
irb(main):007:0> ActiveRecord::Migrator.migrate "./", nil
== 20170501141930 CreateProducts: migrating ===================================
-- create_table(:products)
-> 0.0036s
== 20170501141930 CreateProducts: migrated (0.0037s) ==========================
=> [#<struct ActiveRecord::MigrationProxy name="CreateProducts", version=20170501141930, filename=".//20170501141930_create_products.rb", scope="">]

tips:

  • 除了migrate外,也可以將這次對資料庫的修改回復掉(rollback):
ActiveRecord::Migrator.rollback "./"
  • 可以透過sqlite3命令列工具來檢視資料表的結構:
$ sqlite3 development.sqlite3
CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "price" integer, "detail" text, "created_at" datetime, "updated_at" datetime);
# Ctrl + D 退出

步驟7: 建立 Model 的實例

irb(main):008:0> product = Product.new(name: "Mac Book Pro", price: 33456)
=> #<Product id: nil, name: "Mac Book Pro", price: 33456, detail: nil, created_at: nil, updated_at: nil>
irb(main):009:0> product.save
=> true
irb(main):010:0> product
=> #<Product id: 1, name: "Mac Book Pro", price: 33456, detail: nil, created_at: "2017-05-01 06:42:23", updated_at: "2017-05-01 06:42:23">

除了 new 之後 save 的建立方式外,也可以直接用 create 方式直接建立同時儲存。

以上就完成了ActiveRecord的實作。

ActiveRecord 查找功能

Product.first
Product.all
Product.find(1)
Product.find_by(name: "Mac Book Pro")

ActiveRecord 驗證功能

ActiveRecord支援資料驗證功能,確保資料在存入資料庫前需先通過驗證條件。

require 'active_record'
class Product
< ActiveRecord::Base
# name、price 必須存在
validates :name, :price, presence: true
# name 欄位長度不能超過 128
validates :name, length: { maximum: 128 }
# price 必須是數字且爲整數
validates :price
, numericality: { only_integer: true }
end

參考:

  • 「還在寫PHP?大師才用輕量級Ruby、JavaScript開發Web」- 邱俊濤 / 佳魁資訊