2016-07-29 5 views
0

Я хочу сохранить глобальную переменную, поэтому я не попадаю в базу данных каждый раз, когда ссылаюсь на модели.Сохранение глобальной переменной, содержащей коллекцию моделей

Должен ли я сделать это в инициализаторе или есть другой способ?

$rules = Rule.all 

Эти данные никогда не изменится, если я не изменить кодовую так это прекрасно, чтобы быть обновлена ​​только тогда, когда приложение перезагружается.

Какие у меня варианты?

Я думаю, что я могу сделать это и в моем контроллере:

$rules ||= Rule.all 

Есть ли «лучшей практики» в отношении этого?

+0

Плохая идея. Ну, сначала нужно знать, почему вы хотите, чтобы кэш имел значение? Вы хотите кэшировать значение при загрузке? –

+0

Если данные являются статическими, зачем использовать базу данных вместо простого хеша или массива Ruby? – meagar

+0

@ArupRakshit Да при загрузке. – Blankman

ответ

1

ОК, затем в каталоге config/initializers/ создайте файл load_rules.rb. И внутри этого напишите что-нибудь наподобие:

ActiveSupport.on_load(:active_record) do 
    RULES = Rule.all 
end 

Теперь используйте эту константу в любом месте, которое вы хотите использовать.

+0

Почему он должен использовать объекты ActiveRecord, когда он ничего не делает с базой данных? – siegy22

+0

@RaVeN Он использовал термин _model_. Строка _I хочу сохранить глобальную переменную, поэтому я не попадаю в базу данных каждый раз, когда ссылаюсь на модели_, достаточно для того, чтобы я заключил это решение. Но, как я сказал в вашем ответе на ответ, для статических данных не нужна модель. Я замечаю запах дизайна позже. –

+0

Подождите, так что вы говорите, что «модель» всегда является моделью ActiveRecord? – siegy22

0

Я думаю, вы не хотите использовать базу данных для такой вещи. Вы должны хранить эти значения в виде массива объектов и использовать Rails.app.config.x пространство имен:

так что ваша модель будет выглядеть следующим образом:

#app/models/rule.rb 
class Rule 
    attr_reader :name 

    def initialize(name:) 
    @name = name 
    end 
end 

и ваш инициализаторе:

# config/initializers/rules_initializer.rb 
Rails.application.config.x.rules = [ 
             Rule.new(name: "Admin"), 
             ... 
            ] 
+0

Этот подход потребует изменения кода при изменении набора правил. –

+0

для создания объектов, файл 'seeds.rb' хорош, я так думаю. –

+0

@NicNilov Как бы вы не изменили код, если набор изменился? хранить его в db? – siegy22

1

Я предложил бы использовать низкоуровневое кэширование, завернутое в метод:

class ApplicationCotroller < ActionController::Base 
    # ... 

    def all_rules 
     Rails.cache.fetch("all_rules") do 
     Rule.all 
     end 
    end 

    # ... 
end 

В зависимости от на вашем примере использования метод может быть помещен в одноэлементный класс вместо ApplicationController или в mixin Module.

Главное преимущество этого подхода заключается в том, что вы можете легко перезагрузить правила без перезапуска сервера, удалив ключ кеша из консоли. Хотя вы четко обозначили это как некритический аспект, я думаю, что он добавляет некоторые удобства.

+0

Мне понравился ваш подход к кешу! +1. Причина в том, что мы можем обновлять данные без перезагрузки. Хорошая идея! –

+0

Но 1 вещь, что, если я хочу использовать ее в каком-то другом контексте? Вероятно, вам нужно ввести некоторый тип инициализатора для глобального доступа. –

+1

Да, как я уже упоминал, в зависимости от варианта использования его можно разместить где-то в другом месте, инициализатором является один из вариантов. –

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