Cookies in Rails

Cookies are a developers tool to take stateless HTTP requests and give them state. In other words, they allow us differentiate between a GET request from one browser and a GET request from another. They let us do this by telling each browser to send some data within the body of their request in the form of a params associative array (aka a hash in ruby.) We can then use this data, which we set at some point after the user visits our site (e.g. on login), to figure out which user is which.

Sessions vs. Cookies

Rails gives us some convenient, built in ways to manage cookies. It comes standard with 3 methods: session, flash, and cookies. Two of them (session and cookies) work very similarly, with the exception that the session method encrypts the data so that it can’t be edited by the user.

You can see this difference if you look at your cookies and sessions on a rails server:

$: rails new demo_app

$: rails g scaffold post title body published

Then, inside the post_controller.rb file, add these lines in the create action.

def create
  cookies[:created_post_at] = Date.today
  session[:created_post_at] = Date.today
  ...
end

Then back in your console:

$: rake db:migrate

$: rails s

Now, we can go visit localhost:3000/posts/new, and fill out our form. Afterwards, we should see:
Post Form Created Post

We can now look at our cookies and find: Normal Cookie

Session Cookie

As you can see, the cookies method created a cookie with the name that we passed in as a key, and the value that we set. The session method, however, created a cookie with the name of our app followed by _session and a key that looks like a random string. This string is an encrypted hash that we can access with the session method. Inside this hash, the key created_post_at will have the value 2017-04-19.

Note that, although the session method by default persists data as a cookie, there are other ways that you can use it that will not be covered in this post.

The Flash

Our third method for persisting data is the flash method. The flash method acts as though it is the session method, with the exception that the key-value pair only persists for 1 request.

We can demonstrate this by adding the following code to our controller in the show method:

flash[:display_this] = "You just visited the show page for #{@post.title}"

and this code in our index view:

<% if flash[:display_this].present? %>
  <pre><%= flash[:display_this] %></pre>
<% end %>

Starting from our index page (`localhost:3000/posts’) we can delete all our cookies and navigate to the show page.
Index Original No Cookies

We can then navigate to the show page, and then back to the index page.
Show Page Index Affected

Now, if we look at our cookies we can see that there is only the session cookie. Flash Cookie

At first glance, this will make the flash method seem like it does the same thing as the session method. However, if you refresh your page, you’ll see that the message is gone!

The flash method is also accessible through the redirect_to method. By using the syntax:

redirect_to posts_path, flash: { display_this: "You just visited the show page for #{@post.title}" }

you can prevent the session cookie from being changed until you redirect. You can also make a the flash method accessible in the current action by using:

def update
  if @post.update( posts_params )
    ...
  else
    flash.now[ display_this: "There was a problem updating the #{@post.title} post"]
    render :edit
  end
end

or you can make sure that the flash key-value pairs aren’t deleted from your session hash by using:

flash.keep # persists all values for the flash method

flash.keep[ :display_this ] # persists only the :display_this key-value pair

The flash method also includes some convenient shortcuts for quickly assigning and accessing values of the keys :notice and :alert:

flash.alert = "You must be logged in"
flash.notice = "Post successfully created"

redirect_to root_url, notice: "You have successfully logged out."
redirect_to root_url, alert: "You're stuck here!"

For more information on the cookie method or other ways of using the session method, check out these sites: