Blankman
Blankman

Reputation: 267060

Storing a global variable that holds a collection of models

I want to store a global variable so I don't hit the database each time I reference the models.

Should I do this in an initializer or is there another way?

$rules = Rule.all

This data will never change unless I change the codebase so it is fine to only be refreshed when the app reloads.

What options do I have?

I think I can do this also in my controller:

$rules ||= Rule.all

Is there a "best practise" concerning this?

Upvotes: 0

Views: 425

Answers (3)

Nic Nilov
Nic Nilov

Reputation: 5156

I'd suggest using low-level caching wrapped in a method:

class ApplicationCotroller < ActionController::Base
  # ...

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

  # ...
end

Depending on your use case the method could be placed in a singleton class instead of ApplicationController or in a mixin Module.

The main benefit of this approach is you can easily reload the rules without restarting the server by deleting the cache key from the console. Although you clearly marked this as a non-critical aspect, I think it adds some convenience.

Upvotes: 1

siegy22
siegy22

Reputation: 4413

I think you don't want to use the database for such a thing. You should store these values as an array of objects and use the Rails.app.config.x namespace:

so your model would look like:

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

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

and your initializer:

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

Upvotes: 0

Arup Rakshit
Arup Rakshit

Reputation: 118271

Ok, then inside the config/initializers/ directory create a file like load_rules.rb. And inside that, write something like:

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

Now use this constant anywhere you want to use.

Upvotes: 1

Related Questions