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).

+3


source to share


5 answers


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.

+9


source


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

      

+1


source


I have sometimes used what I called poor cache .

It worked like this:

  • in the initializer add: MY_CACHE_HASH = {}

  • wherever: MY_CACHE_HASH[:foo] = :bar

  • where do you need MY_CACHE_HASH[:foo] #=> :bar

I would not recommend it: what would you do if your server crashes?

0


source


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

...

0


source


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.

0


source







All Articles