Rails and class variables: will this persist between users and server calls?
We are on Rails 3.0.6.
Will the following code persist for loading pages and users in Rails? Or can it be overridden with every request? The code is at the top of the controller.
@@list = []
hero = {}
hero['name'] = 'so'
hero['superpowers'] = ['coding', 'qa', 'spec_writing']
@@list.push hero
hero2 = {}
hero2['name'] = 'so2'
hero2['superpowers'] = ['coding']
@@list.push hero2
... more Hashes pushed into @@list
The list changes only once a month, and we would like to efficiently and quickly make this data available for page requests. We will eventually be able to use Rails.cache to read from the database, but for now we are using the following approach (assuming it works).
source to share
In design, the default behavior is that the class is reloaded on every request, thereby resetting your class variable. However, in production, the class is initialized once, so the class variable will persist across multiple requests and multiple sessions.
You should get to the correct caching technique as soon as you can. You cannot obviously keep the value outside of class reloading when you restart your application. Also, if the web server is multithreaded (as it might be), it can run multiple instances of the application on different threads that don't share class variables, potentially creating inconsistencies between requests.
source to share
I just came across the same problem and found this post. I know this is an old question, but posting my answer in case anyone comes across a similar issue ...
I think for cases where the database or Rails.cache cannot be used for some reason, the best place to put these values is in the Application class. Just define some attribute and initialize it. Then it's easy to access it like Rails.application.heros . A quick and dirty sample below:
in config / application.rb
module YourRailsApp
class Application < Rails::Application
attr_reader :heros
initializer "init heros" do
@heros = []
hero = {}
hero['name'] = 'so'
hero['superpowers'] = ['coding', 'qa', 'spec_writing']
@heros.push hero
hero2 = {}
hero2['name'] = 'so2'
hero2['superpowers'] = ['coding']
@heros.push hero2
end
#Other application sutff...
end
end
source to share
If you have data that won't change while rails are running, great to use @@class_variable
.
Be aware that (in the default config config) the controller classes are reloaded on every request, so if you have to say read the data from the file, consider entering the code to initialize the data in config / application.rb in $global
or CONSTANT_VAR
...
source to share
So what you are describing is a data structure that is not a database. I think it's perfectly reasonable to have items that "never" change in your code, not in your database.
for example you could:
In the app /models/hero.rb
class Hero
@@all_heros = []
def self.all_heros
@@all_heros
end
def self.add_hero(hero)
@@all_heros << hero
end
def initialize(name, superpowers=[])
@name = name
@superpowers = superpowers
end
end
# this will get executed on load
Hero.add_hero( Hero.new("so", ['coding', 'qa', 'spec_writing']))
Then, in your code, you will access:
@heros = Hero.all_heros
And later you can swap the storage location with the database backup if you need.
source to share