2010-10-17 55 views
1

在Rails的導的表,我很困惑過爲什麼has_onehas_many表是相同的:混淆了對HAS_ONE和的has_many

Example tables for has_many

customers(id,name) 
orders(id,customer_id,order_date) 

Example tables for has_one這些在數據庫層面,表還將允許供應商擁有多個帳戶,但我們只需要每個供應商一個帳戶

suppliers(id,name) 
accounts(id,supplier_id,account_number) #Foreign Key to supplier here?? 

不應該爲has_one的表是這樣的,而不是:

suppliers(id,name,account_id) #Foreign Key to account here 
accounts(id,account_number) 

現在因爲account_id是在供應商表,供應商不能有一個以上的賬戶。

Rails指南中的例子不正確嗎?

或者,Rails是否使用has_many類方法,但限制了many部分的發生?

回答

1

如果我正確理解你的問題,你相信有1:1在has_one/belongs_to關係中雙向關係。這不完全正確。你可以有:

Class Account 
    belongs_to :supplier 
    belongs_to :wholesaler 
    belongs_to :shipper 
    # ... 
end 

account = supplier.account  # Get supplier's account 
wholesaler = Wholesaler.new 
wholesaler.accounts << account # Tell wholesaler this is one of their suppliers 
wholesaler.save 

我不是說你的應用程序實際上表現爲這種方式,但你可以看到一個表 - 不,讓我們假設一個模型 - 即「屬於」另一種模式,但不排除從屬於任何數量的模型。對?所以這種關係真的是無限的:1。

我應該補充一點,has_one實際上是has_many的一個退化情況,只是增加了將關聯和其他幾個nits單獨化的語法糖。否則,它幾乎是一回事,這幾乎是他們看起來相似的原因。

+0

謝謝!這給了我一些思考的食物。所以,Rails基本上強制has_one中的「one」。我想知道,這是「安全」的。假定只有一個Rails應用程序將使用數據庫,它應該沒問題。 – Zabba 2010-10-17 06:44:55

+1

Rails的關鍵指導原則之一是它專爲應用程序數據庫而非集成數據庫而設計。這就是爲什麼在應用程序級別而不是數據庫級別執行約束的原因。它驅動DBA堅果:) – 2010-10-17 17:28:41

2

如果你仔細想想這樣的 - 他們都是一樣的:

1客戶可以有很多訂單,所以每個訂單的記錄點回客戶。

1供應商可以有一個帳戶,它是「有很多」的特例,所以它同樣適用於帳戶指向供應商。

多對多的情況也是如此,連接表指向個人記錄......(如果學生可以上很多班,而一個班可以有很多學生,那麼登記表指向學生和班級記錄)。

至於爲什麼帳戶指向供應商vs帳戶指向供應商,我不完全確定我們是否可以擁有它,或者一種形式比另一種更好。

+0

我發現了一些鏈接,可能會有所幫助,只要我仔細研究它們。 http://usernameguy.livejournal.com/5268.html和http://duanesbrain.blogspot.com/2006/05/ruby-on-rails-hasone-versus-belongsto.html。他們對你有意義嗎?特別是第二個鏈接中的信息? – Zabba 2010-10-17 05:07:13

2

我相信它與約束有關。使用has_one導軌將試圖強制每個供應商只有一個帳戶。但是,對於has_many,將不會執行任何限制,因此具有has_many的供應商將被允許存在多個帳戶。

在考慮關係及其在rails中的創建時,需要花費一些時間。如果你想在數據庫端執行外鍵(因爲rails不會在應用程序層以外執行此操作),請看看Mathew Higgins' foreigner

+0

明白了。所以Rails使用has_many方法,但強制只有一個記錄會被關聯 - 正確嗎?如果是這樣,我想這可能是一件好事,在某種程度上。由於對於某些模型,這可能意味着Rails代碼中的一些更改將在未來不會更改數據庫的情況下允許has_many。 – Zabba 2010-10-17 06:46:22

+0

本質上,是的。請注意,這樣做會使您的數據庫癱瘓並且處於較低的完整性水平(在我看來)。很多時候,如果你看看數據庫,你可以弄清楚發生了什麼。但是,如果所有代碼都在應用程序級別上,那麼與不同系統和維護的集成可能會很痛苦。並希望你永遠不會有某種數據不匹配。 – MunkiPhD 2010-10-18 12:05:51