簡體   English   中英

在Rails應用程序中存儲全局應用程序設置的最佳方法是什么?

[英]What's the best way to store global application settings in a Rails application?

我想處理兩種全局配置設置:

  • 可以由用戶更改的設置,例如是否發送特定事件的通知郵件。
  • 與特定產品版本相關聯的設置,例如禁用免費版本中的功能,該功能僅在商業版本中可用。

存儲這些設置的最佳方法是什么? 數據庫,配置文件,在源代碼中硬編碼,......?

對於這兩種情況的數據 你將為多個人/產品使用相同的結構,所以它是有道理的。 它還允許您在不重新啟動服務器的情況下進行更改。

我過去以這種方式處理過:對於特定於用戶的設置,我創建了一個UserSettings模型/表,它與用戶有一對一的關系。 這樣做的原因是我的大多數涉及用戶的操作並不需要加載這些設置,所以它們只在我需要時才包含在數據庫的用戶加載中。

當我這樣做時,我通常會對列名進行分組,以便我可以編寫基於名稱動態創建的幫助程序。 這意味着我不必修改我的視圖以包含新設置,除非我添加一個具有不同命名方案的設置。

對於特定於產品的設置,這取決於您的工作方式。 並且有幾種方法可以解釋您的問題。

我讀它的方式是你想要決定產品水平。 用戶可以覆蓋或禁用用戶設置的設置。 並可能定義一些產品特定的設置。

我會用一對多的產品來設定關系。 設置表將是簡單的(product_id,setting_name,setting_default_value,allow_user_change)

這做了很多事情。 它允許您擁有不同產品的可變設置列表(適用於您提供許多不同產品而非不同層次的服務訪問權限的情況)。 它還允許您定義用戶可以/不可以更改的設置,並為該產品類型提供值。 可以在不重新啟動應用程序的情況下從管理員視圖更改。 它也與用戶設置無關,如果用戶沒有在product_settings中列出設置,那么就沒有問題。

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

您還必須編寫驗證以確保用戶不會更改其產品無法更改的設置。 您還必須編寫幫助方法來合並產品和用戶方的設置。

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

對於基於產品版本的東西,你可能無法真正存儲數據庫中的東西,因為標志將基於某些授權代碼,而不是靜態數據。

這是我對這種東西的體驗: 不要覆蓋行為

你看,你的第一個想法是這樣的:

嗯....系統范圍的設置可能會被用戶(或產品)覆蓋,也可能不會被覆蓋。 嘿! 我知道這個! 它的構成!

從技術上講,你是對的。 因此,您將創建一個“設置”表並將所有設置放在那里。 然后你將擁有一個user_settings表,如果用戶決定,你將覆蓋這些設置。 它會工作正常。

直到您將設置添加到一個表而不是另一個表。

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

然后你會意識到:

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

你是對的。

所以,是的。 繼續並保留數據庫中的設置,但為每個用戶或產品明確保存它們。 在行創建時使用智能默認值,它將保持簡潔。

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

第二種設置將再次進入數據庫。 例如,如果用戶擁有免費帳戶,則會以某種方式保存在數據庫中。 我會在Application中有一些助手,例如“free?” 還是“商業?”。 這些幫助者可以查看它們是真還是假,詢問當前連接的用戶/帳戶模型。 然后,您可以在應用程序的不同部分使用這些幫助程序來決定是否顯示或隱藏某些功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM