(Я согласен с @ user43685 и не согласен с @Derek P - есть много веских причин для сохранения данных по всему сайту в базе данных вместо файла yaml. Например: ваши настройки будут доступны на всех веб-серверах (если у вас несколько веб-серверов); изменения в ваших настройках будут 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 вы должны иметь возможность заменить тело метода «instance» на вызов « first_or_create! » следующим образом:
def self.instance
first_or_create!(singleton_guard: 0)
end