Store session keys as strings not symbols

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the rails category.

Last Updated: 2021-05-15

I had this code in a controller:

before_action :set_landing_page

def set_landing_page
  session[:tracking_info][:landing_page] ||= request.path
end

Its unintended effect was to rewrite the landing page :tracking_info on every request (which is basically the same as not persisting it)

My mistake was that, in Rails, session keys are stored as strings. Symbols will cause errors:

session[:tracking_info] contains {"landing_page"} , not :landing_page

The confusing part is that a hash works for the first key, but not for nested keys... The fix was to use strings all the way

def set_landing_page
# This code rewrote the landing page on every request
  session['tracking_info']['landing_page'] ||= request.path
end
  session['tracking_info']['landing_page'] ||= request.path

Lesson

Use strings for sessions in Rails.

Generally don't assume strings are symbols are interchangeable in Ruby:

a = {}
a[:foo] = 1
a['foo'] = 2
{:foo=>1, "foo"=>2}