繁体   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