2016-09-16 3 views
0

Если у нас есть небольшая таблица, которая содержит относительно статические данные, можно ли активировать Active Record при запуске приложения и никогда не ударять по базе данных для этих данных?Rails 5 Active Record - возможно ли сохранить таблицу в памяти?

Обратите внимание, что в идеале я хотел бы, чтобы эти данные были объединены в другие модели, имеющие отношения к нему.

Примером может служить список стран с их префиксным номером телефона - этот список вряд ли изменится, и если бы это было сделано, это было бы изменено администратором. Другие таблицы могут иметь отношения с этим (например, с учетом Пользователя, имеющего ссылку на страну, мы можем захотеть найти телефонный код страны).

Я видел аналогичный вопрос here, но ему 6 лет и относится к Rails 2, в то время как я использую Rails 5 и, возможно, с тех пор что-то было введено.

Предпочтительные растворы будут:

  1. Встроенная функциональность Рельсы/ActiveRecord, чтобы загрузить таблицу один раз при запуске, и если другие записи впоследствии загружены, в которых есть отношения с кэш-таблице, то ссылку на кэшированную объектов (например, вручную кэшировать MyModel.all где-то недостаточно, так как отношения будут по-прежнему загружаться при запросе базы данных).
  2. Поддерживается библиотека, которая делает выше.
  3. Если ни один из них не доступен, я полагаю, что альтернативным методом было бы определить статический набор данных как enum/hash в памяти или аналогичный, и сохранить хэш-ключ в записях, которые имеют отношение к этим данным, и определить методы на эти модели для поиска с использованием объекта в хэше с использованием ключа, сохраненного в базе данных. Это кажется вполне руководство, хотя ...

[EDIT] Еще одна вещь, чтобы рассмотреть с потенциальными решениями - ручное решение (3) также потребует пользовательские контроллеры и маршруты для таких данных, чтобы быть доступными над API. В идеале было бы неплохо иметь решение, в котором такие данные могут быть предложены через API RESTful (только для чтения - только GET), если это необходимо, с использованием стандартных механизмов рельсов, таких как строительные леса, без чрезмерного вмешательства вручную.

+0

Вы можете использовать 'enum' – RSB

+0

@RSB - Возможно, я ошибаюсь, но не' enum' эффективно действует как строковый идентификатор для числа? Значение enum может быть только одним значением, а не сложным объектом? Это может пригодиться в некоторых обстоятельствах, но я не уверен, что он будет здесь подходящим. например. Если в качестве примера мы снова возьмем префикс страны -> телефон, нам нужна как часть страны, так и телефонная префиксная часть. Кроме того, если у нас есть «Пользователь» и «Компания», им может потребоваться доступ к одному и тому же адресу страны -> телефонному сопоставлению, так что нужно было бы дублировать перечисление в обоих классах модели (или в каком-то родительском классе)? Спасибо – asibs

+0

Я думаю, вам придется использовать опцию 3. 1, на самом деле невозможно, что это не так, как работает sql. вы должны запрашивать базы данных, они являются отдельными технологиями. 2 зависит от того, какую библиотеку вы ищете. Например, Carmen отлично подходит для стран/штатов и хранит эти данные в файлах yml https://github.com/jim/carmen, но если это не те данные, которые вы ищете, тогда вам придется урегулировать для использования их подходов (yml-файлов), которые обновляются вручную. – Sean

ответ

1

Я думаю, что вы можете слишком быстро уклоняться от «простого»/«ручного» подхода.

Запись данных в хэш-массив рубинов не так уж плоха.

И если вы хотите использовать CRUD-эшафот, почему бы просто не использовать стандартную модель Rails/контроллер? Неужели так плохо хранить некоторые статические данные в базе данных?

Третий вариант заключается в том, чтобы хранить ваши данные в файле в каком-то сериализованном формате, а затем, когда ваше приложение загружает, прочитайте это и создайте объекты ActiveRecord. Позвольте мне привести пример:

данные.YML

--- 
- a: "1" 
    b: "1" 
- a: "2" 
    b: "2" 

Это YAML файл, содержащий массив хэшей; Вы можете построить такой файл с:

require 'yaml' 
File.open("path.yml", "w") do |f| 
    data = [ 
    { "a" => "1", "b" => 1 }, 
    { "a" => "2", "b" => 2 } 
    ] 
    f.write(YAML.dump(data)) 
end 

Затем, чтобы загрузить данные, вы можете создать файл в config/initializers/ (здесь все будет Автозагружаемого по рельсам):

конфигурации/инициализаторы/static_data.rb

require 'yaml' 

# define a constant that can be used by the rest of the app 
StaticData = YAML.load(File.read("data.yml")).map do |object| 
    MyObjectClass.new(object) 
end 

чтобы избежать необходимости писать миграции базы данных для MyObjectClass (если это на самом деле не хранятся в БД), вы можете использовать attr_accessor определения для вашего Атрибуты:

class MyObjectClass < ActiveRecord::Base 
    # say these are your two columns 
    attr_accessor :a, :b 
end 

просто убедитесь, что не запускать такие вещи, как save, delete или update на этой модели (если вы не monkeypatch этих методов).

Если вы хотите иметь конечные точки REST/CRUD, вам нужно будет написать их с нуля, потому что теперь можно изменить данные. Вам в основном нужно делать какие-либо обновления в 3 этапа:

  1. нагрузку данные из YAML в список объектов Ruby,
  2. изменить список рубин объект
  3. сериализовать все, чтобы YAML и сохранить его ,

Итак, вы можете видеть, что здесь вы не делаете инкрементных обновлений. Вы можете использовать JSON вместо YAML, и у вас будет такая же проблема. С построенной в Ruby системой хранения PStore вы сможете обновлять объекты на индивидуальной основе, но использование SQL для производственного веб-приложения является гораздо лучшей идеей и, честно говоря, сделает вещи более простыми.

Переходя за пределы этих «сериализованных данных», есть серверы хранения ключей, хранящиеся в памяти. Такие вещи, как Memcached и Redis.

Но, чтобы вернуться к моему предыдущему моменту, если у вас нет веских оснований не использовать SQL, вы делаете только труднее.

+0

У меня такая же ситуация.Я не хочу хранить в db, потому что он слишком мал, и запросы для них довольно большие. Обновление этих данных также очень редко. Итак, какой-то коучинг в памяти или что-нибудь, чтобы избежать дополнительных запросов, было бы здорово. Мне не нравится подход Yaml или json, поскольку я думаю, что обновление будет сложным. – Anwar

+0

Итак, сохраните его в памяти. Я не знаю, каков ваш вопрос. –

Смежные вопросы