Part 5: Personalization with GET
When we have captured some form input data, and want to use it on a different page, our first impulse is to send this data along as local variables while redirecting to the new URL; someting like this:
get '/' do
erb :'index'
end
post '/' do
# NB! Cannot do this:
redirect '/thank-you', :locals => { :name => params[:name] }
end
get '/thank-you' do
# Try referencing the `name` variable in the template:
erb :"thank-you"
end
This, however, is not going to work.
HTTP is a stateless protocol. Requests don't share information; any data exhanged between client and server is not available to subsequent (or previous) requests. Here, that last GET
request has no way of accessing the local variable(s) present in the POST
request that's doing the redirect.
This means that we need to pass this information from one request to the next by including it in the URL. First we construct the URL, then redirect to it:
get '/' do
erb :'index'
end
post '/' do
redirect "/thank-you/#{params[:name]}"
end
get '/thank-you/:name' do
erb :"thank-you", :locals => { :name => params[:name] }
end
This also means that we need modify the route for our "thank you" page, by appending a wildcard that can hold the value of the name
parameter.
Now this GET
request can fetch the name from the URL, and display it in the body of the response:
<h2 class="no-margin">Thank you, <%= name %>!</h2>
(Here's the complete thank-you template).
Notice that in order to make this interaction dynamic, we needed to modify the information architecture of our app. We went from a "thank you" page that does not specify a recipient to one that does — by modifying the last segment of the URL:
http://localhost:9292/thank-you/Alice
This is what REST is about; because HTTP is a stateless protocol, we must use URL layout to describe resources. The HTTP verbs then define the actions that can be performed on those resources.