Cookies in Ruby on Rails. You can’t store Arrays in there

Yesterday I decide to implement a simple feature in iccfriends that allow people to track who is already their friend, but I didn’t want to use the db so I opted for local storage and went with a cookie.

I read the rails docs about the cookies method and decided to give it a try with this code:

def foo
  if cookies[:friends].blank?
    cookies[:friends] = [params[:id]]
  else
    cookies[:friends] = cookies[:friends] << params[:id]
  end
end

It seemed to work correctly but the Array was converted to a String before going in the cookie. This is where my cookie ignorance showed as I tried again and again to store an Array in it, to no avail.

After googling around for a little while I discovered there was no way I could store an object in the cookie without some sort of serialization, so I had to use good old Array#join and String#split.

def bar_write
  if cookies[:friends].blank?
    cookies[:friends] = params[:id]
  else
    cookies[:friends] = cookies[:friends] << ",#{params[:id]}"
  end
end
 
def bar_read
  @var = cookies[:friends] ? cookies[:friends].split(",") || []
end

7 Responses to “Cookies in Ruby on Rails. You can’t store Arrays in there”

  1. mystery man Says:

    Instead of split and join, how about to_yaml and YAML.load

  2. Giovanni Intini Says:

    I didn’t want to add the YAML overhead since it’s simply an array of integers.

  3. Federico Says:

    A more compact way that makes use of method chaining:

    def bar_write
    cookies[:friends] = cookies[:friends].to_s.split(’,’).push(params[:id].to_s).join(’,’)
    end

    def bar_read
    cookies[:friends].to_s.split(’,’)
    end

  4. Giovanni Intini Says:

    Federico you get an exception if cookies[:friends] is nil using your method.

  5. Federico Says:

    Mmmh… are you sure? :)

    irb(main):007:0> nil.to_s.split(’,’).push(‘a’.to_s).join(’,’)
    => “a”
    irb(main):008:0> nil.to_s.split(’,’)
    => []

    the to_s call is there to prevent the exception! :)

  6. Giovanni Intini Says:

    I totally overlooked that, I didn’t no nil had a to_s :)

    Thanks for the tip!

  7. Ben Strackany Says:

    Yep we found this out, too. No built-in subcookies, boo. Thing is, you can pass a hash as a value, but it expects that hash to be a list of cookie parameters (e.g. value, path, expiration, etc).