A Route for POST Requests8:47 with Jay McGavren
We've set our new wiki page form up to submit via an HTTP POST request. But we're getting the error "Sinatra doesn't know this ditty". The problem is that we need to set up a Sinatra route to handle POST requests.
We've set our new wiki page form up to submit via an HTTP POST request, but 0:00 we're getting the error Sinatra doesn't know this ditty. 0:05 The problem is that we need to set up a Sinatra route to handle POST requests. 0:08 Down here Sinatra provides us with a sample route to get us started, 0:12 post to the /create path. 0:16 Let's go back in our main app code and add a post route there. 0:18 Just as you used Sinatra's GET method to set up routes to handle HTTP GET requests, 0:23 you use Sinatra's POST method to set up routes for HTTP POST requests. 0:28 The post method works in much the same way as the get method. 0:34 You call the method and 0:37 pass of a string with the request path should match /create in this case. 0:38 Then you pass it a block that should be called whenever a matching post 0:45 request is received. 0:48 For now we'll just have the block respond to the browser with a string. 0:52 Hello from the post "/create" route! 0:56 By the way, you may be remembering how our get new route 1:06 conflicted with the URL parameter in the get title route. 1:10 You may be wondering if it's okay to define our post 1:14 create route down here at the bottom of the file. 1:16 There's no need to worry. 1:19 None of the get routes will match our post request no matter what the path 1:20 is because the request type is different. 1:24 We might need to be concerned if there were another post route with 1:26 a URL parameter. 1:29 But since this is the only post route, 1:30 we can define it anywhere in the file we want. 1:32 Let's test this new route. 1:35 Remember because we made a change to our Ruby code, 1:37 we have to restart the server even if it's already running. 1:39 Now, I'll visit form to create a new page, fill it out. 1:46 And then submit it, which should send a POST request to the /create path. 1:59 And in response, 2:04 instead of an error, we see our string, Hello from the post "/create" route! 2:04 Our route is being mapped successfully. 2:09 Displaying placeholder messages is all fine and good, but 2:11 we need a route to take our form data and save a new Wiki page for us. 2:14 Remember our route to view an individual page which 2:19 got the page title from a URL parameter? 2:22 That parameter was made available within the route block through the params hash. 2:25 Form parameters from POST requests also get placed into the params hash. 2:29 We can look at the form parameters by calling the inspect 2:34 method on params which converts the hash to a string. 2:37 So I'll replace our placeholder text, and 2:40 get the parames hash and call the inspect method on it. 2:43 Now if we restart the server, and fill out the form. 2:48 And submit it, we'll see the title we entered under the title key. 2:57 And the content we entered under the content key. 3:02 Let's copy this string, and 3:05 paste it temporarily in a comment right above our route so we can refer to it. 3:07 So remember the save content method we set up previously? 3:19 It takes the title string and the content string. 3:24 And saves the content to a text file for us. 3:28 And now we finally have the title and the content ready to pass to it is input. 3:31 We'll call save_content within our route block. 3:38 For the title, we'll pass it the value from the title key of the params hash. 3:41 And for the content, we'll pass it the value from 3:51 the content key, params["content"]. 3:56 Let's restart our server again. 4:01 We'll visit the new page form. 4:07 It's already filled out from our prior submission, and let's submit it again. 4:11 We'll see only a blank page in response. 4:15 But if we go back to our workspace, refresh our file list, 4:18 And look in the pages directory, we'll see a text file with the page 4:24 title we entered as its name and the contents we entered as its content. 4:28 If we go back to the preview again, fill out the form again, And submit it again, 4:33 we'll get another blank page but, we can go back to the workspace, refresh again. 4:42 And we'll see another new file based on our form contents. 4:46 We're successfully saving our form data. 4:51 There is one more detail to take care of. 4:53 We don't want the browser to just show a blank page after we submit the form. 4:57 So the final thing we'll do is tell the browser to make a GET 5:00 request to show the new page after it's saved. 5:03 To do that will add a call to the redirect method at the end of a route block. 5:06 The redirect method tells Sinatra to send a redirect response to the browser, 5:10 redirects cause the browser to send the GET requests for a particular URL or path. 5:15 Whatever string you pass to the redirect method, that's the URL or 5:20 path the browser will be redirected to. 5:23 The path for the new page will consist of a slash followed by the page title. 5:26 So we'll use the title parameter to construct the path for the redirect. 5:30 So we'll start the string with a slash and then interpolate the title parameter, 5:33 Into the string. 5:44 Our route should be complete now, so 5:45 we shouldn't need the reference comment anymore. 5:48 Let's delete that. 5:50 Let's restart the server again. 5:52 Now we can go back to the new page form. 5:55 Submit a new page. 5:58 And once the page is saved we'll be redirected to view it. 6:03 This works fine until we try to submit a new page that has a space in the title. 6:07 At that point the page will seem to lock up and 6:12 may eventually return a 502 bad gateway message. 6:14 We've seen that when Sinatra starts up it prints a bunch of debug 6:18 messages to the terminal. 6:21 If Sinatra encounters any errors while it's running, 6:23 the error messages get logged in the terminal too. 6:25 Let's go back to our workspace and look at the Sinatra log messages in the console. 6:28 We'll scroll up until we find the problem. 6:33 InvalidURIError. 6:38 URI basically means the same thing as URL. 6:40 We'll also see the URL that the create route tried to redirect us to. 6:44 The problem is that spaces aren't a valid character within a URL, 6:49 they need to be encoded. 6:53 If you type a space into your browser address bar or 6:55 click on a link with a space, it'll be okay. 6:57 Let's try this here, Alena Holligan, note the space in there. 7:00 Your browser encodes the space characters when it sends the request. 7:07 But when we're sending a redirect back to the browser, 7:10 we need to encode the URL ourselves. 7:13 We can do that with the URI module. 7:17 It's part of the Ruby standard library, 7:19 which means it's included with every Ruby distribution. 7:21 The URI escape method can escape that is, encode the redirect path for us. 7:24 First we're going to need to load the URI library at the top of the file, 7:30 right here and to require "sinatra" we'll type, require 'uri". 7:34 Note that it's named uri, 7:39 not URL, if you type URL here, the library will fail to load. 7:41 Then we'll take our redirect path and pass it exactly as it is URI.escape. 7:47 The return value of URI.escape 7:52 will be the same path string except that if it contains any bases or 7:56 other invalid characters, they'll be encoded so the path is valid. 8:00 Now let's restart our server. 8:05 And now I'll try submitting a page with a space in the title again. 8:08 We've already got the form filled out, let's click Submit. 8:12 And this time we're successfully redirected to the new page. 8:15 And there are no errors from Sinatra logged in the console. 8:18 Our users can create new pages now, nice work. 8:23 We set up one Sinatra route that lets users send GET requests for 8:26 a new HTML form. 8:29 Then we set up a second route that accepts POST requests with the form data and 8:31 saves it to a file. 8:35 We've shown you techniques to load existing page data and 8:38 to save new page data. 8:41 In the next stage, 8:42 we'll combine those abilities to let users edit existing pages. 8:43
You need to sign up for Treehouse in order to download course files.Sign up