2011-05-24 67 views
2

比方說,我有三個表格:users,booksusers_books應該在哪裏用Acl進行過濾?

在我的一個觀點中,我想顯示當前用戶有權訪問的所有書籍的列表。如果在users_books中存在與用戶和書籍匹配的行,則用戶可以訪問書籍。

有(至少)兩種方式,我可以做到這一點:

  • 在我的books模型fetchAll()方法,在users_books表上執行某種形式的join
  • 在Acl插件中,首先從每本書中創建一個資源。然後,爲每個用戶創建一個角色。接下來,根據users_books表允許或拒絕用戶訪問每個資源。最後,在books模型的fetchAll()方法中,使用當前用戶作爲角色,在我們找到的每本書上調用isAllowed()

我把最後一個選項看成是最好的選擇,因爲那時我可以在我的應用程序的其他地方使用Acl。這將消除執行重複訪問檢查的需要。

你會建議什麼?

回答

1

我推了這一切到數據庫:

  1. 做它在數據庫中通過JOIN的將是一個很大的速度比在你的PHP過濾的東西。
  2. 在數據庫中做它可以讓你正確地分頁,而不必像獲取更多數據那樣跳躍(如果你最終拋出太多,那麼獲取更多數據)。

我可以想到兩種可用於管理ACL的廣泛策略。

你可以建立數據庫中的顯式ACL與單個表的排序是這樣的:

  • id:的東西有問題的ID(圖書,圖片,...)。
  • id_type:id來自的類型或表。
  • user:可以看東西的用戶。

的(idid_type)對給你一個僞FK,您可以使用爲健全檢查您的數據庫和id_type可以用來選擇一個類提供必要的膠水互動型特異性的部分ACL並將SQL片段添加到查詢以正確加入ACL表。

或者,您可以使用命名約定將ACL邊框表附加到每個表上,而不需要ACL。對於表t,你可以有一個表t_acl與像列:

  • id:的東西t的ID(與完整性的真正的外鍵)。
  • user:用戶可以看看這個東西。

然後,您可以有一個ACL類,可以根據基表名稱調整您的SQL。

第一種方法的主要優點是您有一個單一的ACL存儲區,因此很容易回答諸如「用戶X可以看什麼?」之類的問題。第二種方法的主要優點是,您可以擁有真正的參照完整性和更少的代碼(通過命名約定)將它們粘合在一起。

希望以上內容能幫助您的思考。

+0

謝謝你,我決定使用你的第二種方法。在每個請求中構建整個Acl都沒有意義,因爲大多數頁面都不會使用它。再次感謝! – 2011-05-24 23:14:00

1

我會從模型中分離出數據庫訪問代碼,方法是在存儲庫類中使用像getBooksByUser(User $ user)這樣的add方法創建finder方法來返回書對象的集合。

不完全確定您需要從您描述的ACL獲取ACL。我可能錯了。