An Edit Form5:31 with Jay McGavren
We have a controller action set up to load an existing Page model object for editing. Now we just need to present a form to edit it with.
We have a controller action set up to load an existing page model 0:00 objects for editing. 0:03 Now we just need to present a form to edit it with. 0:05 The view for editing and the existing page object can actually be identical to 0:08 the form for entering a new page object in every way. 0:12 So for our first version of this template, 0:15 let's open up an app > views > pages > new.html.erb. 0:19 Select everything in the file and 0:26 copy it over to edit.html.erb replacing the old contents. 0:28 Remember when we called form four to set up a form for a new page object? 0:34 Because all of the objects attributes were nil, 0:38 all the fields in the resulting form were blank. 0:41 But we can actually use the exact same form code for editing a page object. 0:44 The only difference is that all of the objects attributes will be populated. 0:49 So instead of the user seeing blank fields, all of the form 0:53 fields will be populated with the existing values of the objects' attributes. 0:56 Our form starts off with a call to the form_for method with the page 1:02 instance variable as an argument. 1:06 But before this variable held a reference to a new empty page object, 1:09 this time the object has been loaded from the database and 1:13 all its attributes are populated. 1:16 As with the new page form, an object representing the HTML form will be 1:18 passed to the f block parameter so we can use it to add fields. 1:22 Also as with the new page form will need fields for the title, body and 1:27 slug attributes. 1:31 But because the attributes to the object we passed the form_for 1:32 are already populated, the form objects will generate HTML for 1:35 fields prefilled with those attribute values. 1:39 So let's save this. 1:43 If we reload the browser, we'll see our edit form. 1:44 All of the fields are pre-populated with the attributes of the page 1:47 object we loaded. 1:50 Of course, we can't submit the form yet, 1:52 we haven't set up a controller action to handle the submission. 1:55 But it looks like the form is displaying correctly. 1:58 Well that was easy, but we don't want to get in the habit of copying and 2:01 pasting code. 2:04 As the software development maxim goes, don't repeat yourself, 2:06 it's dangerous to have repeated code in multiple places in your app. 2:10 We used partials briefly in the previous course and 2:14 it would be a good idea to use them again here. 2:16 We have an element of our page, the form, 2:19 that needs to look identical in multiple places in our app. 2:21 But just copying the code from one place to another is a bad idea, if we needed to 2:25 change the form we might update the code in one place but forget the others. 2:29 The versions could wind up looking different or even stop working altogether. 2:33 Instead it's better to use partials, we can take the identical form code and 2:38 move it to a partial template. 2:42 Then each template that needs the form can render the partial and 2:44 the form code will be included in that template. 2:47 So let's convert our duplicated form code into a partial. 2:50 First, we'll cut all of the form code out of the edit.html.erb template. 2:54 Then we'll create a new file in that same folder called _form.html.erb, 2:59 remember partial template file names need to begin with an underscore. 3:06 Create that file and we'll paste all the form code into that partial. 3:11 Now we need to reference the partial from the templates that need to include it. 3:16 We'll go back into the edit template and we'll embed a call to the render method. 3:20 So we'll do an output embedding tag with render. 3:25 We need a template name to render so we'll pass it a string of form. 3:30 And that will render the _form.html.erb file. 3:36 Remember, Rails adds on the underscore and the .html.erb automatically. 3:40 Now we need to pass data into our partial view, 3:45 we do that by adding keyword arguments to the render method. 3:47 Each keyword that we add here will become a local variable, and 3:50 each value that we pass in here will be the value of that local variable. 3:54 So we're going to set up a local variable named page and 4:00 we'll pass it the page object in our page instance variable as its value. 4:03 That means that within the partial we're going to need to reference the page local 4:08 variable rather than the page instance variable. 4:12 So we'll go back into the partial and replace the reference to @page 4:15 the instance variable with just page the local variable. 4:19 Ensure all the editor files are saved and then reload the browser. 4:23 The result is the same, 4:27 the form is just being loaded from the partial instead of the main template. 4:29 Now let's go into the template for a new form and load the partial there as well. 4:33 We can replace all this code with a single line, 4:37 we'll embed the results of a call to render. 4:39 Render the form partial, again remember the underscore character isn't needed. 4:43 And just as we did in the other template, 4:48 we'll set up a local variable named page with the current page object. 4:50 And if we visit the form for a new page we can 4:56 see that even though it's now being loaded from a partial the result is the same. 5:00 We've successfully gotten rid of our redundant code. 5:05 Our form data an existing page looks great but as we saw before, with our 5:08 form to create new pages, if we click the button to submit it, we'll see an error. 5:14 No route matches [PATCH] "/pages/7" followed by the ID. 5:18 The difference is that with the new page form it was looking for 5:22 a post route, this time it's looking for a patch route. 5:25 We'll fix that issue next. 5:29
You need to sign up for Treehouse in order to download course files.Sign up