為你的 N:M Join Table 加入屬性
出自我的 Blog
http://lightyror.blogspot.com/2006/11/nm-join-table.html
N:M Join Table 一般來說,通常只有兩個 Column ,兩個都是另外兩個 table 的 Foreign Key。舉例來說,假設今天有兩個 Table ,一個是 people ,另外一個是 firend_relations。人跟人之間的朋友關係由 friend_relations 來描述,所以 friend_relations 裡面的欄位應該有
1. person_id
2. friend_person_id
根據 Agile Web Development with Rails這本書,裡面有一段話
Active Record automatically includes all columns from the join tables when accessing rows using it. If the join table included a column called id, its id would overwrite the id of the rows in the joined table.
如果 join table 裡面,加上 id 這個欄位的話,當我們使用
Person.find(1).friends.each do |friend|
puts friend.id
end
這裡的 i.id 不是朋友在 people 這個 table 裡面的 id ,反而是 Join Table friend_relations 的 id 。也就是說,Join Table 裡面除了 Foreign Key 以外的欄位,都會覆蓋掉所有關聯性 Table 的欄位。這在 Coding 時,很容易造成混淆,必須盡量避免。
但是有時候這個特性很好用,假設有一需求。我想知道我跟你之間的朋友關係是啥時建立的?我們如果將這個時間 created_at 寫在 Join_Table frined_relations 裡面,那麼
Person.find(1).friends.each do |friend|
puts frined.created_at
end
這裡的 i.created_at 就是 freind_relations 裡面的 created_at (朋友關係建立的時間),而非 people 裡面的 created_at (person 資料建立的時間),因為已經被覆蓋掉了。的確,當你使用到 person.friends 的時候,通常你在使用 朋友關係 的資料,而非 這個人的基本資料 ,所以他被覆蓋過去也是很合理的。
我們還可以在 friend_relations 加入 relation 這個 column ,裡面放 '點頭之交' ,'朋友' ,'好友','密友' 之類的關係,可以作出
Person.find(1).friends.each do |friend|
puts friend.name+'是'+friend.relation
end
結果就會出現
小李是好友
小王是點頭之交
小陳是朋友
之類的結果,可說是相當方便的特性。
結論
我個人將這個特性視為雙面刃。沒有良好的命名規劃,很有可能造成很大的混亂,但是當你自己了解你在幹嘛時,功能卻又方便而且強大。
--
lighty RoR 是一個介紹 lighttpd , SQLite , Ruby and Rails 的 Blog
http://lightyror.blogspot.com/
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.230.103.247
→
11/01 22:31, , 1F
11/01 22:31, 1F
→
11/01 22:32, , 2F
11/01 22:32, 2F
→
11/02 01:09, , 3F
11/02 01:09, 3F
→
11/02 01:11, , 4F
11/02 01:11, 4F
討論串 (同標題文章)
以下文章回應了本文:
完整討論串 (本文為第 1 之 2 篇):
Ruby 近期熱門文章
PTT數位生活區 即時熱門文章