Reputation: 267060
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
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
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
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