2010-11-25 122 views
1

嗨,大家好,我在這裏思考這個問題太久就陷入僵局。Rails協會:HABTM?

背景:鑑於以下型號:

  • 用戶
  • 項目
  • 鎖定

這裏的場景:一個鎖基本上是像一個 '持有'。用戶可以在任何給定物品上放置一個「鎖定」,以通知系統該物品不應該被刪除。在清除鎖定之前項目不會被刪除。

這是棘手的部分。鎖是它自己的模型,因爲我希望多個用戶能夠鎖定任何給定的項目。所以我們假設鮑勃鎖定了一個物品,一個物品尚不存在,因此它爲該物品創建了一個鎖,以及說明鮑勃當前與該鎖相關聯的信息。約翰來了並鎖定相同的物品,但鎖已經存在,所以約翰被簡單地添加到同一個鎖下。在所有用戶選擇「解鎖」或取消關聯自己的鎖之前,鎖不會被刪除。

我的困惑是我應該如何建模這些關係。用戶當然可以擁有許多鎖,每個鎖都與一個不同的項目相關聯(因爲任何給定的項目最多隻能有一個鎖)。鎖本身可以有很多用戶。從該項目的角度來看,每個項目可以有一個與許多用戶相關聯的鎖。

因此,換句話說,我想訪問的信息少了一些這樣的:

item.lock.users # get the users 'locking' the item 
user.locks # get the items the user is currently 'locking 

也許不需要單獨鎖定模式,但我想這將是爲了表示該多個用戶可以鎖定一個特定的項目。

我覺得更復雜的事情是,用戶添加的項目,所以我想有一種方式來訪問用戶的項目,例如user.itemsitem.user

現在我有:

  • 用戶屬於許多鎖
  • 鎖具有屬於許多用戶
  • 用戶有很多項目
  • 項目屬於用戶
  • 項目有一把鎖
  • 鎖屬於物品

這看起來正確嗎?

回答

3

我認爲你正在做的事情會工作,雖然你可能不需要使用habtm。如果一個物品可以有多個鎖,並且只有在沒有鎖的情況下才能刪除,該怎麼辦?這樣你可以爲用戶添加每個鎖的日期/理由/評論。

  • 用戶
    • 的has_many:鎖定
    • 的has_many:項目
    • belongs_to的:用戶
    • belongs_to的:項目
  • 項目
    • belongs_to的:用戶
    • 的has_many:鎖

這仍然會允許你這樣做user.locks雖然item.lock.users將無法​​正常工作,但通過查看每個鎖,你會很容易地能夠獲得用戶。

item.locks.each do |lock| 
    puts lock.user 
end 
+0

哇!這麼簡單,我想得太過分了,我完全沒有想到它。非常感謝!兩次,你已經幫了我:) – 2010-11-25 23:41:33

+0

我很高興幫助。 – rwilliams 2010-11-25 23:55:05

2

您不需要鎖定模型。你可以簡單地設置用戶和項目之間的關係HABTM:

class User < ActiveRecord::Base 
    has_many :items 
    has_and_belongs_to_many :locks, :class_name => "Item" 
end 

User.first.items # => [<#Item>, <#Item>, ...] # Items created by user 
User.first.locks # => [<#Item>, <#Item>, ...] # Items locked by user 

class Item < ActiveRecord::Base 
    belongs_to :user 
    has_and_belongs_to_many :lock_users, :class_name => "User" 
end 

Item.first.user # => <#User> # Creator of the item 
Item.first.lock_users # => [<#User>, <#User>, ...] # "Lockers" of the item 

你必須創建一個連接表,當然,同時也要注意的是什麼Rails的希望被命名的連接表。您可能會更好地指定habtm的:join_table選項。

這裏的關鍵在於Rails中的關係非常靈活。你可以在兩個表之間有多個關係;您可以同時擁有「創建者」和鎖定關係,彼此獨立。你所要做的就是爲關係使用不同的名字。

+0

有趣的構建vonconrad。我很感激,但我認爲我更容易理解rwilliams的答案。雖然謝謝! – 2010-11-25 23:44:59

1

我可以說「考慮這個太久了」。當這種想法悄悄進入我的腦海時,我退後一步並在代碼的其他部分工作。隨着時間的推移,關係似乎會顯現出來,因爲它們讓我們能夠編寫一堆代碼非常方便。它們不是必需的,所以至少在開發階段,我們可以推遲關係的聲明,稍後再看看我們需要什麼。

是的,我們應該總是根據實用主義者提前知道,但在現實生活中,我們經常不得不使用常識和經驗,建立一個工作原型,然後對其進行微調。正是在這個微調階段,我調整了之前不完全清晰的關係,並調整了我的代碼。

嗅嗅......嗅......哎呀,現在我的老闆知道我並不完美......嗅....

回到手頭上的問題:通常情況下,鎖以防止意外(或故意)刪除,我在我的主表中創建一個布爾字段,如果該記錄應該被清除設置爲true。對於你在做什麼,我可能會完全擺脫標誌字段,並有一個單獨的表,即要鎖定的記錄的ID,以及想保留該記錄的用戶ID。如果他們認爲是時候刪除記錄,請刪除這些用戶的記錄。當是時候做一些清理工作時,我會檢查那張桌子。類似的東西來:

delete from table1 where id not in (select distinct(table1_id) from table2) 

我不喜歡它的東西是有潛力,有另一個滿桌的「保持這個紀錄」記載,這就是當我添加另一個表,供用戶終止誰可以」決定需要刪除的東西。