1 00:00:00,730 --> 00:00:03,600 We've set up a route, so that form submissions get sent to 2 00:00:03,600 --> 00:00:08,030 the pages controllers create method, but that method doesn't exist yet. 3 00:00:08,030 --> 00:00:09,510 Let's set it up now. 4 00:00:09,510 --> 00:00:14,640 We'll go into the app controllers folder, open up the pages controller, 5 00:00:14,640 --> 00:00:18,420 and add a new create method down here at the bottom. 6 00:00:21,250 --> 00:00:25,330 Within the method, our form parameters will be available within the params 7 00:00:25,330 --> 00:00:29,310 object, just like the URL parameters were before. 8 00:00:29,310 --> 00:00:31,738 Let's look at the contents of params. 9 00:00:31,738 --> 00:00:33,840 We'll render our responses as plain text, so 10 00:00:33,840 --> 00:00:36,040 we don't have to create in the RB template. 11 00:00:36,040 --> 00:00:42,810 So, we'll call render, and we'll give it a keyword argument of text. 12 00:00:42,810 --> 00:00:46,600 Then we'll take the params objects and call a method name to_json on it 13 00:00:46,600 --> 00:00:50,020 to convert it to JavaScript object notation format. 14 00:00:50,020 --> 00:00:53,390 That will allow us to see the entire object easily. 15 00:00:53,390 --> 00:00:58,130 Save that, and resubmit the form, and you'll see Json similar to this. 16 00:00:59,200 --> 00:01:03,040 Let's try to use these parameters to create a new page object. 17 00:01:03,040 --> 00:01:05,590 We'll assign our object to the page instance variable. 18 00:01:07,070 --> 00:01:12,800 To create the object, we'll call page.new, and pass the parameters as an argument. 19 00:01:15,520 --> 00:01:17,190 Save that and go back to our browser. 20 00:01:18,490 --> 00:01:23,290 But if we resubmit the form, we'll see an active model forbid an attribute error. 21 00:01:23,290 --> 00:01:26,970 The problem is that we tried to use parameters to create a new model object 22 00:01:26,970 --> 00:01:30,720 without specifying which parameters are allowed for use. 23 00:01:30,720 --> 00:01:34,620 Remember how we showed you a scenario where a malicious user added the parameter 24 00:01:34,620 --> 00:01:39,330 to a POST request turning himself into a site admin and causing all sorts of havoc? 25 00:01:39,330 --> 00:01:40,800 That's what's going on here, 26 00:01:40,800 --> 00:01:44,520 rails is trying to protect your app from unwanted parameters. 27 00:01:44,520 --> 00:01:47,560 That's why rails uses the strong parameters library. 28 00:01:47,560 --> 00:01:51,830 Strong parameters helps keep your apps from hacked, by requiring you to specify 29 00:01:51,830 --> 00:01:55,540 which parameters are allowed, before you can use them to create a model object. 30 00:01:56,660 --> 00:02:00,670 Let's look at the contents of params again, and see which ones we should allow. 31 00:02:00,670 --> 00:02:03,820 We'll delete this line that creates a new page from our controller. 32 00:02:03,820 --> 00:02:07,069 And then we'll resubmit our form data to see the parameters. 33 00:02:09,970 --> 00:02:13,280 There's a bunch of stuff, like the authenticity token and 34 00:02:13,280 --> 00:02:15,750 the controller parameters that we don't really need. 35 00:02:15,750 --> 00:02:18,370 Rails just uses those internally. 36 00:02:18,370 --> 00:02:20,730 So, we'll need to discard those. 37 00:02:20,730 --> 00:02:24,720 It looks like everything we actually need to build a page object is nested here in 38 00:02:24,720 --> 00:02:28,450 this group of parameters, and if I scroll off to the right here, 39 00:02:28,450 --> 00:02:33,130 you can see that that is all stored under the page parameter. 40 00:02:33,130 --> 00:02:37,820 The page parameter has this other parameters object nested under it. 41 00:02:37,820 --> 00:02:42,880 The parameters object that's nested under page itself has title, body, and 42 00:02:42,880 --> 00:02:44,750 slug parameters. 43 00:02:44,750 --> 00:02:47,940 The object in params acts a lot like a hash with keys and 44 00:02:47,940 --> 00:02:51,610 values you can access, but it's actually not a hash. 45 00:02:51,610 --> 00:02:54,409 Let's update our controller to show you the class of params. 46 00:02:56,230 --> 00:02:59,840 So, we'll change sets a params.class. 47 00:02:59,840 --> 00:03:02,740 Reload and confirm our form resubmission. 48 00:03:03,960 --> 00:03:07,395 And you can see it's actually an action controller parameters object. 49 00:03:07,395 --> 00:03:10,010 So, why doesn't rails just use a hash? 50 00:03:10,010 --> 00:03:14,103 Among other things, an action controller parameters object has a convenient require 51 00:03:14,103 --> 00:03:18,190 method that allows you to specify that certain parameters have to be present, 52 00:03:18,190 --> 00:03:23,220 as well as a permit method that allows you to specify which parameters are allowed. 53 00:03:23,220 --> 00:03:25,950 Let me show you how this works in the rails consul. 54 00:03:25,950 --> 00:03:29,158 So, we'll go back to our terminal, quit out of our server if it's running. 55 00:03:29,158 --> 00:03:34,090 And run bin/rails c to launch the console. 56 00:03:35,570 --> 00:03:39,510 First, I'll manually create my own action controller parameters object and 57 00:03:39,510 --> 00:03:41,230 assign it to the program's variable. 58 00:03:42,760 --> 00:03:46,804 So, we'll set up our variable, and then call action controller, 59 00:03:49,786 --> 00:03:54,725 Parameters.new. 60 00:03:54,725 --> 00:03:58,110 I'll spread this over several lines since that's pretty long. 61 00:03:58,110 --> 00:04:00,131 So first, I'll throw our parameter, and 62 00:04:00,131 --> 00:04:03,230 there are to represent all the stuff that Rails uses internally. 63 00:04:07,130 --> 00:04:11,380 I'll put a comma there, which will allow me to go down to another line. 64 00:04:11,380 --> 00:04:15,260 And we'll mess to bunch of other parameters under the page parameter. 65 00:04:15,260 --> 00:04:16,460 So, we'll say page. 66 00:04:17,630 --> 00:04:22,050 And then we'll put a hash here, which will give us a nested parameter object, 67 00:04:22,050 --> 00:04:24,520 once this parameter object is created. 68 00:04:25,710 --> 00:04:31,178 Within that hash, we'll set up a title parameter, with value of title. 69 00:04:31,178 --> 00:04:35,913 Body of body, and 70 00:04:35,913 --> 00:04:40,020 a slug of slug. 71 00:04:41,660 --> 00:04:45,700 Let's also throw in a fake malicious parameter in there. 72 00:04:45,700 --> 00:04:50,660 Remember, we had an attacker try to add and is admin attribute before. 73 00:04:50,660 --> 00:04:52,440 We'll try adding that here, as well. 74 00:04:55,415 --> 00:04:57,435 We'll end our page parameter, and 75 00:04:57,435 --> 00:05:02,170 we'll end the entire action controller parameters new call. 76 00:05:02,170 --> 00:05:04,970 The Rails consul shows the resulting object. 77 00:05:04,970 --> 00:05:07,270 Notice this permit that should be done on the end here. 78 00:05:08,510 --> 00:05:11,700 If you try to use an action controller parameters object where 79 00:05:11,700 --> 00:05:15,440 permitted is false to set an object's attributes, you'll get an error. 80 00:05:15,440 --> 00:05:18,180 So, let's try creating a new page object. 81 00:05:19,190 --> 00:05:23,300 We'll called page .new, and we'll pass at this prams object, and 82 00:05:23,300 --> 00:05:25,470 remember, permitted is false on this object. 83 00:05:26,740 --> 00:05:28,500 We get an error. 84 00:05:28,500 --> 00:05:31,762 Scroll up to show you, active model for bed and 85 00:05:31,762 --> 00:05:34,840 attributes error, just like we saw in our browser earlier. 86 00:05:34,840 --> 00:05:37,380 That's the strong parameters protection kicking in. 87 00:05:38,720 --> 00:05:41,650 Before we can use these parameters to update model objects, 88 00:05:41,650 --> 00:05:45,280 we're going to need to indicate which parameters are required to be present. 89 00:05:45,280 --> 00:05:48,070 So, that requests without them can be rejected. 90 00:05:48,070 --> 00:05:51,150 We'll also need to indicate which parameters are permitted, so 91 00:05:51,150 --> 00:05:55,030 that other possibly malicious parameters can be discarded. 92 00:05:55,030 --> 00:05:56,900 For example, that is admin attribute. 93 00:05:58,120 --> 00:06:02,940 Let's start by indicating a parameter that's required using the required method. 94 00:06:02,940 --> 00:06:05,860 All the parameters we actually want title body and 95 00:06:05,860 --> 00:06:11,710 slug are nested in another parameter object under the page parameter. 96 00:06:11,710 --> 00:06:15,150 We wouldn't want to accept any requests that didn't include page. 97 00:06:15,150 --> 00:06:19,300 So, we'll call require with a symbol, page. 98 00:06:20,870 --> 00:06:24,610 The require method returns the value of the parameter being required, which, 99 00:06:24,610 --> 00:06:28,380 in this case, is another action controller parameters object. 100 00:06:28,380 --> 00:06:32,030 Notice that permitted is also false on this object. 101 00:06:32,030 --> 00:06:36,340 That's because we didn't get this object by calling the permit method, so 102 00:06:36,340 --> 00:06:38,730 we still can't use it to create a model object. 103 00:06:39,920 --> 00:06:43,660 Now, let's try calling permit on this new parameters object to indicate which 104 00:06:43,660 --> 00:06:48,200 parameters are permitted, and to discard that unwanted is admin parameter. 105 00:06:48,200 --> 00:06:49,650 We'll chain the methods together. 106 00:06:49,650 --> 00:06:53,450 Calling permit directly on the return value of require. 107 00:06:53,450 --> 00:06:56,330 We'll permit just the title parameter for now. 108 00:06:56,330 --> 00:06:59,210 So, we'll pass a symbol of title to the permit method. 109 00:07:00,410 --> 00:07:02,470 We got back a new parameters object. 110 00:07:02,470 --> 00:07:06,920 It contains only the title parameter, since that was the only one we permitted. 111 00:07:06,920 --> 00:07:10,660 And notice that the permitted attribute is now set to true. 112 00:07:10,660 --> 00:07:15,060 That means we can use this parameters object to create a new page object. 113 00:07:15,060 --> 00:07:15,930 Let's try that out. 114 00:07:15,930 --> 00:07:21,160 We'll take the same command and pass the result to a call to page that new. 115 00:07:21,160 --> 00:07:23,260 So, page.new here at the beginning. 116 00:07:24,360 --> 00:07:27,770 And we'll wrap all this in parentheses. 117 00:07:27,770 --> 00:07:30,090 So, we take our programs object. 118 00:07:30,090 --> 00:07:34,690 We require the page parameter, we permit the title parameter within that object, 119 00:07:34,690 --> 00:07:36,815 and then we pass the whole thing to page.new. 120 00:07:38,730 --> 00:07:42,140 And instead of an error, we'll get a new page object back. 121 00:07:42,140 --> 00:07:45,700 Only the title attribute has been set on the page though. 122 00:07:45,700 --> 00:07:48,010 So now, let's permit the other parameters. 123 00:07:48,010 --> 00:07:51,660 Permit takes any number of arguments, each representing a parameter you want to 124 00:07:51,660 --> 00:07:55,150 prevent, so we can add on a body parameter. 125 00:07:56,970 --> 00:08:00,260 And the body attribute of our page objects will be set. 126 00:08:00,260 --> 00:08:02,220 Finally, we can add on the slug parameter. 127 00:08:05,290 --> 00:08:07,680 And the slug attribute will be set as well, 128 00:08:07,680 --> 00:08:11,060 there's also no sign of that malicious is admin parameter. 129 00:08:11,060 --> 00:08:14,730 We've successfully used parameters to build a page object. 130 00:08:14,730 --> 00:08:17,350 Of course, these are just fake user parameters. 131 00:08:17,350 --> 00:08:20,030 So now, let's do the same thing for the parameters from our form. 132 00:08:21,970 --> 00:08:24,490 Lex at the consul, we start our rail server, 133 00:08:24,490 --> 00:08:27,030 since we're going to need that in a moment. 134 00:08:27,030 --> 00:08:28,670 Okay, and here in the create method, 135 00:08:28,670 --> 00:08:34,030 which is going to process the mission from our form for a new page. 136 00:08:34,030 --> 00:08:40,460 We're going to set up a page params variable to hold our parameters object, 137 00:08:40,460 --> 00:08:44,790 and the parameters coming back from the form will be in params. 138 00:08:44,790 --> 00:08:48,550 So, within the page parameter of that parameters objects, 139 00:08:48,550 --> 00:08:51,300 the other parameters we need are nested. 140 00:08:51,300 --> 00:08:55,280 So, we're gonna call, we're gonna require the page parameter. 141 00:08:57,460 --> 00:09:00,810 And that will get us a parameter object back, then on that object, 142 00:09:00,810 --> 00:09:01,760 we're going to call permit. 143 00:09:03,500 --> 00:09:10,430 And we're going to permit the title, Bonnie and slug parameters. 144 00:09:10,430 --> 00:09:15,070 And the resulting parameters objects will get stored in the page_params variable. 145 00:09:15,070 --> 00:09:16,900 Now, we'll take that parameters objects, and 146 00:09:16,900 --> 00:09:19,970 can create a new page object based on it. 147 00:09:19,970 --> 00:09:23,780 So, we'll call page.new pass page prams to it. 148 00:09:26,370 --> 00:09:30,180 And that should get us a new page object with its title body and slug and 149 00:09:30,180 --> 00:09:31,390 attributes set. 150 00:09:31,390 --> 00:09:35,330 We'll assign the result to the page instance variable. 151 00:09:35,330 --> 00:09:38,050 Lastly, we want to save that page record to our database. 152 00:09:38,050 --> 00:09:41,310 So, we'll take the page object and we'll call save on it. 153 00:09:42,550 --> 00:09:47,590 So, let's hit save in our editor, go back to our browser, and resubmit our form. 154 00:09:47,590 --> 00:09:54,730 And there's no error this time, actually nothing at all seems to happen. 155 00:09:54,730 --> 00:09:57,250 But if we go back to our list of all pages and 156 00:09:57,250 --> 00:09:59,580 refresh the browser, there is our new page. 157 00:10:00,790 --> 00:10:03,600 We don't want the browser to just sit there showing the form after we've 158 00:10:03,600 --> 00:10:04,900 submitted them. 159 00:10:04,900 --> 00:10:07,990 So, the final thing we'll do is to tell the browser to load the view for 160 00:10:07,990 --> 00:10:09,440 the new page once it's saved. 161 00:10:10,450 --> 00:10:13,490 To do this, we'll add a call to the redirect two method. 162 00:10:16,355 --> 00:10:18,860 We'll pass redirect to our new page object. 163 00:10:19,940 --> 00:10:24,780 The redirect to method tells Rails to send a redirect response to the browser. 164 00:10:24,780 --> 00:10:27,980 Redirects caused the browser to request a new URL. 165 00:10:27,980 --> 00:10:31,780 In this case, since we're passing a page object to redirect to, 166 00:10:31,780 --> 00:10:36,116 the browser will be told to request the URL of that page object. 167 00:10:36,116 --> 00:10:39,720 So, we save this, go back to our browser, and 168 00:10:39,720 --> 00:10:44,520 bring up the new page form and submit it. 169 00:10:46,530 --> 00:10:50,370 Once the record is saved, we will be redirected to view that page. 170 00:10:50,370 --> 00:10:54,040 We've learned a lot about Rails of strong parameters library in this video. 171 00:10:54,040 --> 00:10:56,929 If you'd like to know more, be sure to check out the teachers notes. 172 00:10:58,680 --> 00:10:59,590 Impressive. 173 00:10:59,590 --> 00:11:03,370 You had to set up two routes for this stage, one for get requests for a form, 174 00:11:03,370 --> 00:11:06,250 and another for post requests to submit the form data. 175 00:11:06,250 --> 00:11:10,460 You set up a controller action and a view to display the form, and 176 00:11:10,460 --> 00:11:14,350 another controller action to create a new model object based on the form data. 177 00:11:15,550 --> 00:11:16,990 The tough part is over. 178 00:11:16,990 --> 00:11:21,700 In the next stage, we're going to set up a form to let users modify existing pages. 179 00:11:21,700 --> 00:11:24,680 We'll be following much the same pattern that we did in this stage. 180 00:11:24,680 --> 00:11:27,510 We'll present the form, and then accept form submissions.