2009-10-11 109 views

回答

6

適用於兩種情況下的數據庫。您將爲多個人/產品使用相同的結構,因此它很有意義。此外,它還允許您在不重新啓動服務器的情況下更改內容。

我已經用這種方式處理它: 對於特定於用戶的設置,我創建了一個UserSettings模型/表,它與用戶有一對一的關係。其原因是,我涉及用戶的大多數操作都不需要加載這些設置,因此只有在我需要時才從數據庫加載用戶。

當我這樣做時,通常會將我的列名分組,以便我可以編寫基於名稱動態創建的助手。這意味着我不必修改我的視圖來合併新的設置,除非我添加一個不同的命名方案。

對於產品特定的設置,以及取決於您如何做事情。有幾種方法可以解釋你的問題。

我閱讀它的方式是您要決定產品級別。用戶可以覆蓋或禁用用戶設置的設置。並可能定義一些產品特定的設置。

我會使用一對多產品來設置關係。設置表將是簡單化的東西(product_id,setting_name,setting_default_value,allow_user_change)

這會做很多事情。它允許您爲不同產品設置可變列表(適用於您提供許多不同產品而不是各種訪問服務的情況)。它還允許您定義用戶可以/不能更改的設置,併爲該產品類型提供值。可以在不重新啓動應用程序的情況下從管理員視圖更改。它也與用戶設置無關,如果用戶沒有在product_settings中列出的設置,則不會出現問題。

不足之處是您將在此表中有多個常用設置。我會移動每個產品對產品表中的字段具有不同值的設置。

您還必須編寫驗證以確保用戶不會更改他們產品說不能設置的設置。您還必須編寫幫助器方法來合併產品和用戶方的設置。

0

這是我對這種東西的體驗:不重寫行爲

你看,你首先想到的會是這樣的:

嗯....有可能會或可能不會被用戶(或產品)覆蓋整個系統的設置。嘿!我知道這個!它的組成!

從技術上講,你會是對的。所以,你將創建一個設置表,並把所有的設置放在那裏。然後,您將擁有一個user_settings表,您將在其中覆蓋這些設置,如果用戶決定。它會正常工作。

直到您將設置添加到一個表,而不是其他。

或者您得到一個錯誤,即設置X無法在用戶或產品級別覆蓋,並且需要超過5秒才能確切確定設置的設置。

然後你就會明白:

嘿,我跟蹤的所有至少在兩個不同的地方這些設置。這似乎有點愚蠢。

你會說得對的。

所以,是的。繼續並將設置保存在數據庫中,但爲每個用戶或產品明確保存。在創建行時使用智能默認值,它會讓事情變得更加簡單。

+1

你已經對他在想什麼以及他將如何實現這一點做出各種假設,但他的實際問題是「什麼是存儲這些設置的最佳方式?」在這種情況下,你的假設都沒有任何意義。我認爲這不是一個「稻草人」的資格,但我不確定還有什麼可稱之爲的。 – 2009-10-12 13:44:46

0

對於第一種設置,我將它們保留在用戶模型(用戶表)中。

第二種設置將再次進入數據庫。例如,如果用戶有一個免費賬戶,那麼會以某種方式保存在數據庫中。我會在應用程序中有一些助手,例如「免費?」或「商業?」。這些助手可以找出它們是真是假,詢問當前連接的用戶/賬戶模型。然後,您可以在應用程序的不同部分中使用這些助手來決定是否顯示或隱藏某些功能。

+0

你必須非規範化才能做到這一點。可能是以序列化設置字段的形式。不一定是壞事,但反規範化總是一個折衷。 – 2009-10-12 14:57:39

1
class Flag < ActiveRecord::Base 
    # id, user_id, name, value (serialized probably) 

    belongs_to :user 

    DEFAULTS = { 
    "newsletter" => false 
    } 

    def self.lookup(user, flag) 
    # Please involve memcached here 
    case flag 
    when "ssl_enabled" 
     # Check if user has paid for sufficient access to SSL 
     return false 
    else 
     stored_flag = self.find_by_user_id_and_name(user.id, flag) 
     if stored_flag 
     return stored_flag.value 
     else 
     return DEFAULTS[flag] 
     end 
    end 
    end 
end 

class User < ActiveRecord::Base 
    has_many :flags 

    def flag(name) 
    return Flag.lookup(self, name) 
    end 
end 

對於東西爲基礎的產品版本這,你可能不能真正存儲在數據庫中的東西,因爲該標誌將是基於某些部分的授權碼,而不是靜態的數據。

相關問題