ActiveRecord 核心特色在於「零配置」:繼承 ActiveRecord::Base 的類別,會在執行時透過資料庫結構自動建立屬性存取器,無需在模型中宣告欄位。
-- SQL 建表
create table orders (
id int not null auto_increment,
name varchar(100) not null,
email varchar(255) not null,
address text not null,
pay_type char(10) not null,
shipped_at datetime null,
primary key (id)
);
# Ruby 模型
class Order < ActiveRecord::Base
end
require 'pp'
pp Order.columns.map { |col| col.name }
# => ["id", "name", "email", "address", "pay_type", "shipped_at"]
pp Order.columns_hash['shipped_at']
# => #<ActiveRecord::ConnectionAdapters::Column:0x... @name="shipped_at", @type=:datetime, ...>
order = Order.new
order.shipped_at = "2005-03-04 12:34"
pp order.shipped_at.class # => Time
pp order.shipped_at # => Fri Mar 04 12:34:00 CST 2005
字串自動解析為 Time 物件,展示 ActiveRecord 的型別轉換能力。
| SQL 型別 | Ruby 類別 | 備註 |
|---|---|---|
| int, integer | Fixnum | |
| float, double | Float | |
| decimal, numeric | Float | ⚠️ 浮點數精度問題,貨幣建議用整數存分 |
| char, varchar, string | String | |
| clob, blob, text | String | |
| datetime, time | Time | |
| date | Date | |
| boolean | TrueClass/FalseClass | 後續詳細說明 |
資料庫 decimal(10,2) 映射為 Ruby Float,連續運算會產生捨入誤差(如 0.1 + 0.2 ≠ 0.3)。解決方案:
composed_of 將多個欄位(如 dollars, cents)封裝為 Money 值物件,封裝精度邏輯。