An Update Action5:52 with Jay McGavren
We've successfully created a form for editing an existing Page, and populated it with the Page's attributes. But if we submit the form, we see that a so-called HTTP PATCH request is being sent by the browser, and there's no route for that type of request. So to process these requests, we'll need to go into routes.rb add a PATCH route.
A controller action to update an existing model object usually performs these operations:
def update # Look up the existing model record based # on an ID from the request path. @page = Page.find(params[:id]) # Filter the form parameters to ensure no # malicious parameters were added. page_params = params.require(:page).permit(:title, :body, :slug) # Use the filtered parameters to update # the existing model record. @page.update(page_parameters) # Redirect the browser to another location # so that it doesn't just sit there displaying # the submitted form. redirect_to @page end
We've successfully created a form for editing and the existing page and 0:00 populated it with the pages attributes, but if we submit the form, 0:04 we see that the so-called HTTP patch request is being sent by the browser and 0:08 there's no route for that type of request. 0:12 When you're modifying existing data on the server rather than adding new data, 0:15 you're supposed to use a put or patch request rather than a post request. 0:19 So when you click the submit button on the edit form, 0:24 that's what your browser sends to the server, a patch request. 0:26 Actually, it's technically still a post request coming for the browser but 0:30 it has some added parameters indicating it should be treated as a patch request and 0:34 Rails converts the request type to patch internally. 0:38 So to process these requests we'll need to go into routes.rb and add a patch route. 0:41 Just as we use the get method for get routes and the post method for 0:46 post routes, we call the patch method to create a patch route. 0:49 We can do it here at the bottom of the list, the order doesn't matter. 0:54 Let's go to our browser and look at the HTML for the edit form. 0:57 We can see that its action attribute is set to submit to a path of pages 1:02 followed by the page ID. 1:06 The ID is provided so that we can look the record up in the database just like we do 1:08 with the show and edit pass. 1:12 Once we found the record in the database we can use the form parameters 1:14 to update it. 1:17 So that's the path we use in our route slash pages followed by another slash and 1:19 an ID parameter. 1:25 We'll direct all matching requests to the pages controllers, Update method. 1:27 Save our work and now we need to define that update method on the controller. 1:35 So we'll go app controllers, pages controller and 1:39 we'll add an update method here at the bottom. 1:44 We'll start by using the ID parameter to look up the model object 1:49 just like we do in the show and edit it actions. 1:52 We'll sign it to a page instance variable and we'll 1:54 call a page.find params id, taking the parameter from the URL. 2:00 After that, the code for 2:07 our update method will look very similar to the code in our create method. 2:08 We will create a page params variable to hold our filtered list parameters and 2:13 then we'll take our params object. 2:17 We'll require the page parameter and will permit 2:20 title body and slug parameters. 2:28 Instead of passing those parameters to page.new to create a new page, 2:34 we'll pass them to the update method on the page object that we loaded in. 2:38 So we'll take our page object and we'll call update and 2:43 we'll pass it a filtered set of parameters. 2:47 That will update all the objects attributes with the parameters from 2:52 the form and then automatically save it. 2:55 Finally, just like in the create method we'll redirect the browser to view 2:58 the updated page. 3:01 Now if we visit an edit form in our browser, modify the page. 3:08 And then submit it the result will be saved. 3:19 There's one more small thing we need to fix before we wrap up the stage. 3:28 We've already talked about the dry principle, 3:33 don't repeat yourself as it relates to partial templates. 3:35 But the same is true for your Ruby code. 3:38 We have identical code in our create an update methods to require some form of 3:41 parameters and permit others. 3:45 But what if you added a new attribute? 3:47 You might permit it in the create method but 3:49 forget to do the same in the update method. 3:51 Suddenly your new page form would work correctly but 3:53 your edit page form wouldn't. 3:56 It would be better to have a single copy of that code that's utilized by 3:58 both the create and update methods. 4:01 That's why a code for requiring imprinting parameters is frequently 4:03 placed in a separate method within the controller. 4:07 Other methods such as create an update can just call this parameters method and 4:09 use its return value to create or update model objects. 4:13 All we have to do is move the code that requires and 4:17 permits parameters to a new method. 4:19 We'll name the method page params, 4:21 just like the variable we were assigning to in the create an update methods. 4:24 We'll paste our code in and 4:30 then we can delete the assignments to the page param's variable. 4:32 References of the page_params variable will not simply be treated as if they were 4:37 a call to the page_params method. 4:41 The page_params method returns a parameters object and 4:44 those parameters will be used to create or update page objects. 4:48 The page_params method should only be used inside the pages control or class so 4:53 it's probably best marked method private so no one else attempts to call it. 4:59 One way to mark it private is to put the private keyword before it. 5:03 All methods defined following the private keyword will then be marked private. 5:07 Many developers like to indent those methods an extra level so 5:11 that it's clear they are private. 5:15 Let's go back to our browser and test the parameters will still work for a new page. 5:17 They do, and will try editing the save page as well. 5:24 Works just fine. 5:32 That's another feature finished. 5:35 You created an edit control erection the presents a form pre-populated 5:37 with an existing model objects data. 5:41 Then you added an update action that accepts the form parameters and 5:43 updates the model object. 5:47 One stage to go and it will be short and sweet see you there. 5:49
You need to sign up for Treehouse in order to download course files.Sign up