Entries Tagged 'instance variables' ↓

Persistent Instance Variables in Ruby on Rails

I just recently built a rake task in my project where I wanted to loop through a list of Users, queue up some data for each one, then loop back through them again to process the data that had been queued. I didn’t need the data to live for very long, but I needed it for 2 separate requests.

The problem with this is that in Ruby on Rails, instance variables are not persistent across requests. This means their scope is limited to one usage of an object and the next time you call for that object, the variable is gone.

Unfortunately, the only solution I could imagine for my problem without persistent instance variables was to create a massive join table to connect my generated data between Users. Not only would this have been a lot of work, it would have been a big waste considering the data would have only lived for about a minute as the rake task was executed.

I wanted to improve/increase the scope of instance variables, and so my solution was to take advantage of Class Variables.

At the bottom of my User class, I now have the following:

    def late_employees
      @@late_employees ||= {}
      @@late_employees[self] ||= {}
    def late_team_members
      @@late_team_members ||= {}
      @@late_team_members[self] ||= {}
    def clear_late_emails
      @@late_employees[self] = {}
      @@late_team_members[self] = {}

As you can see, each element of the Class Variable hashes are referenced by the current instance. So when I call u.late_employees, it’s always the same across requests until either I call u.clear_late_emails or the server dies.

To use them, just treat them like any normal instance method/variable. Here is an example of how you can do that:

def employee_late(user, days)
  if user.manager == self
    late_team_members[user] = days
    late_employees[user] = days

def has_late_employees?
  !(late_employees.empty? and late_team_members.empty?)

def send_late_employee_emails
  if has_late_employees?
  length = late_employees.length + late_team_members.length

Voila, instance variables that are persistent across requests!