一個客戶會擁有多個訂單,這形成了一對多關聯,可以使用has_many:
class Customer < ActiveRecord::Base
has_many :orders
end
若如上定義,預設在orders表格上,必須有個customer_id欄位作為外鍵,參考至customers表格的id主鍵。例如:
class CreateCustomers < ActiveRecord::Migration
def change
create_table :customers do |t|
t.string :name
t.timestamps
end
end
end
class CreateOrders < ActiveRecord::Migration
def change
create_table :orders do |t|
t.integer :customer_id # 外鍵
t.datetime :order_date
t.timestamps
end
end
end
has_many會在模型上加入一些方法:
- collection(force_reload = false)
- collection<<(object, …)
- collection.delete(object, …)
- collection=objects
- collection_singular_ids
- collection_singular_ids=ids
- collection.clear
- collection.empty?
- collection.size
- collection.find(…)
- collection.where(…)
- collection.exists?(…)
- collection.build(attributes = {}, …)
- collection.create(attributes = {})
collection是關聯的物件複數名稱,例如orders這樣的名稱。一個儲存的例子如下所示:
c = Customer.new(:name => "Justin")
c.orders.build(:order_date => Time.now) # 建立第一筆訂單
c.orders.build(:order_date => Time.now) # 建立第二筆訂單
c.save
儲存時會先儲存Customer,再分別儲存兩筆Order,也就是會下三次SQL:
INSERT INTO "customers" ("created_at", "name", "updated_at") VALUES (?, ?, ?)
INSERT INTO "orders" ("created_at", "customer_id", "order_date", "updated_at") VALUES (?, ?, ?, ?)
INSERT INTO "orders" ("created_at", "customer_id", "order_date", "updated_at") VALUES (?, ?, ?, ?)
如果查找客戶時,預設訂單是不會一併查詢出來的。例如:
c = Customer.find(1)
orders = c.orders # 此時才從orders表格中查詢訂單
當然,客戶與訂單的關係,也可以說某訂單屬於某客戶,也就是如下:
# app/models/order.rb
class Order < ActiveRecord::Base
belongs_to :customer
end
從訂單看客戶,就是多對一的關係,此時就必須如下儲存:
c = Customer.new(:name => "Justin")
o1 = Order.new(:customer => c, :order_date => Time.now)
o2 = Order.new(:customer => c, :order_date => Time.now)
o1.save
o2.save
o1儲存時會先儲存c,以上會下三次SQL:
INSERT INTO "customers" ("created_at", "name", "updated_at") VALUES (?, ?, ?)
INSERT INTO "orders" ("created_at", "customer_id", "order_date", "updated_at") VALUES (?, ?, ?, ?)
INSERT INTO "orders" ("created_at", "customer_id", "order_date", "updated_at") VALUES (?, ?, ?, ?)