Posted by
前陣子寫了兩篇關於建立好友名單的文章:Rails: 建立好友名單、Rails: 建立好友名單(續)加上好友描述,文中有提到,除非有特殊需求,否則建議建立多對多關係請盡量使用has_and_belongs_to_many(habtm)或has_many :through的方式來建立。
我個人比較常用到的是has_many :through,也就是本篇的主題。
本範例將建立物品清單管理,每個使用者擁有多個物品,例如A擁有電腦、手機、相機;使用者設定物品清單的時候可以建立描述,例如紀錄購入時間、價格或是其他文字描述等等。
首先建立兩個Model分別為User、Item,分別對應到Users以及Items資料表,另外建立記錄兩者relationship的Model及Table,使用migration來建立內容如下:
# db/migrate/001_create_users.rb
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column :name, :string, :null => false
t.column :created_at, :datetime
end
end
def self.down
drop_table :users
end
end
# db/migrate/002_create_items.rb
class CreateItems < ActiveRecord::Migration
def self.up
create_table :items do |t|
t.column :name, :string, :null => false
t.column :description, :text
t.column :created_at, :datetime
end
end
def self.down
drop_table :items
end
end
# db/migrate/003_create_ownerships.rb
class CreateOwnerships < ActiveRecord::Migration
def self.up
create_table
wnerships do |t|
t.column :user_id, :integer, :null => false
t.column :item_id, :integer, :null => false
t.column :description, :text
t.column :created_at, :datetime
t.column :updated_at, :datetime
end
end
def self.down
drop_table
wnerships
end
end
Model的程式如下,簡單來說就是透過第三個Model來記錄兩個Model之間的關係:
# app/models/item.rb class Item < ActiveRecord::Base has_manywnerships has_many :users, :through =>
wnerships end # app/models/user.rb class User < ActiveRecord::Base has_many
wnerships has_many :items, :through =>
wnerships end # app/models/ownership.rb class Ownership < ActiveRecord::Base belongs_to :item belongs_to :user end
如此一來,就可以用下列指令來增加User, Item,並且可以查詢到某User所有的items,或是
擁有某item的users。
peter = User.create(:name => "Peter") deduce = User.create(:name => "Deduce") phone = Item.create(:name => "phone") camera = Item.create(:name => "camera") peter.items << phone peter.items.count phone.users.count