(我同意@user43685 不同意@Derek P - 有很多充分的理由将站点范围的数据保存在数据库中而不是 yaml 文件中。例如:您的设置将在所有 Web 服务器上可用(如果您有多个 Web 服务器);对设置的更改将是 ACID;您不必花时间实现 YAML 包装器等)
在 Rails 中,这很容易实现,您只需要记住您的模型应该是数据库术语中的“单例”,而不是 ruby 对象术语。
实现这一点的最简单方法是:
- 添加一个新模型,为您需要的每个属性添加一列
- 添加一个名为“singleton_guard”的特殊列,并验证它始终等于“0”,并将其标记为唯一(这将强制该表在数据库中只有一行)
- 向模型类添加静态辅助方法以加载单例行
所以迁移应该是这样的:
create_table :app_settings do |t|
t.integer :singleton_guard
t.datetime :config_property1
t.datetime :config_property2
...
t.timestamps
end
add_index(:app_settings, :singleton_guard, :unique => true)
模型类应该是这样的:
class AppSettings < ActiveRecord::Base
# The "singleton_guard" column is a unique column which must always be set to '0'
# This ensures that only one AppSettings row is created
validates_inclusion_of :singleton_guard, :in => [0]
def self.instance
# there will be only one row, and its ID must be '1'
begin
find(1)
rescue ActiveRecord::RecordNotFound
# slight race condition here, but it will only happen once
row = AppSettings.new
row.singleton_guard = 0
row.save!
row
end
end
end
在 Rails >= 3.2.1 中,您应该能够通过调用“ first_or_create! ”来替换“实例”getter 的主体,如下所示:
def self.instance
first_or_create!(singleton_guard: 0)
end