Cookies in Ruby on Rails. You can’t store Arrays in there
Posted by Giovanni Intini | Filed under Programming, Ruby, Ruby on Rails
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
June 8th, 2007 at 6:24 pm
Instead of split and join, how about to_yaml and YAML.load
June 8th, 2007 at 10:57 pm
I didn’t want to add the YAML overhead since it’s simply an array of integers.
June 9th, 2007 at 12:07 pm
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
June 9th, 2007 at 7:28 pm
Federico you get an exception if cookies[:friends] is nil using your method.
June 9th, 2007 at 9:19 pm
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!
June 10th, 2007 at 11:21 pm
I totally overlooked that, I didn’t no nil had a to_s
Thanks for the tip!
January 10th, 2009 at 2:47 am
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).