Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Updating Views4:58 with Jay McGavren
Our "Post" model objects have a "body" attribute now, but that attribute doesn't show up on our site anywhere. In order to fix this, we're going to need to update the affected views to display the "body" attribute.
Let's open "app/views/posts/index.html.erb" in our editor. This template is creating an HTML table of all the posts and their attributes. If you want to learn more about HTML tables, see the HTML Tables course.
... <table> <thead> <tr> <th>Title</th> <th>Body</th> <!--Add header here--> <th colspan="3"></th> </tr> </thead> <tbody> <!-- Process each post --> <% @posts.each do |post| %> <tr> <!-- The current post's title --> <td><%= post.title %></td> <!-- Add body attribute here --> <td><%= post.body %></td> <td><%= link_to 'Show', post %></td> ...
If we save our work and reload the page, we'll see a body for the post that we edited in the Rails console. We'll see blank bodies for the other posts (since they're still blank in the database).
Now, let's add the body attribute in the view for a single post. Edit the "app/views/posts/show.html.erb" file.
... <!-- Existing post title code here --> <p> <strong>Title:</strong> <%= @post.title %> </p> <!-- Add a new HTML paragraph tag... --> <p> <!-- With the post body embedded inside. --> <%= @post.body %> </p> ...
When we edit an existing post, or create a new post, we're not given a field to edit the body attribute. We want to fix that next. But when we edit the ERB template at "app/views/posts/edit.html.erb", we don't see HTML to render a form directly. The same is true for "app/views/posts/new.html.erb". Instead, we see a call to the "render" method with an argument of "form".
<%= render 'form', post: @post %>
When "render" is called from either of these templates, it looks up a "partial". "Partial" is short for "partial view". And it's this partial that contains the HTML code for the form.
You can take the HTML code that's identical between two templates, and move it to a partial view. Then, each template that needs that code can render the partial, and the partial's code will be included in the template's code. When you need to make a change, you only have to update the partial. Any changes you make will immediately be visible in all the views that use that partial.
So both the edit post page and the new post page include a call to render a partial called "form". If we look at the log, we'll see it's been showing us the step where it renders the partial all along. Within both the "edit" and "new" requests, we'll see
- The underscore at the start of the file name indicates that a file holds a partial template.
- When calling "render", you can leave the underscore and the ".html.erb" extension off. Rails can add those automatically. That leaves just "render 'form'".
- Following the name of the partial is a hash that sets up local variables for use within the partial. So this will make the
@postinstance variable available within the partial as the "post" local variable.
Let's open the partial file to see what it contains. It's at "app/views/posts/_form.html.erb".
<%= form_for(post) do |f| %> <!-- Trimming error display code --> <!-- Existing title field --> <div class="field"> <%= f.label :title %> <%= f.text_field :title %> </div> <!-- Create a new div element to hold body --> <div class="field"> <!-- The label that appears next to field --> <%= f.label :body %> <!-- The field itself --> <!-- Using text_area instead of text_field <!-- makes it bigger --> <%= f.text_area :body %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>
- We can see that it takes the "post" object we passed in, and renders an HTML form for it.
- The "f" variable here will hold a Ruby object representing the HTML form. We can call methods on that object to add elements to the HTML form.
Our post model objects have a body attribute now but
that attribute doesn't show up on our site anywhere.
If we view the list of all posts or an individual post all we see is the title.
If we add a new post or edit an existing one, we only have a field for the title.
In order to fix this,
we're going to need to update the affected views to display the body attribute.
We do this by updating the ERB templates, that render the HTML pages.
First lets display the body attribute in the list of all posts.
Remember when we took a detailed look at how rails responds to our request.
We request the post path and
we see Rendering posts/index.html.erb in the log.
So let's open the app, views, posts,
Index.html.erb in our editor.
This template is creating an HTML table of all the posts and their attributes.
If you wanna learn more about HTML tables, see the teacher's notes for more info.
First up are the table headers across the top of the table.
There's one here for Title, let's add another for body.
So we'll just copy this line, paste it, and give it a heading a Body.
Then we have this code which loops through each of the posts and
outputs a table row for that post.
With each post that gets processed the post block parameter
get set to the current post.
The ERB tags within this loop will be output repeatedly but
the values they insert into the HTML will vary based on the current post.
We already have a table data element that embeds the title attribute for
the current post, let's have another one that embeds the body attribute.
And so again we'll copy, we'll paste and we'll modify
the title access or to access the body attribute instead.
If we save our work and reload the page, we'll see a body for
the posts that we added it in the rails console.
We'll see blank bodies for
the other posts, since they're still blank in the database.
By the way, we don't have to restart the server or anything for this.
When we're developing a new app, Rails reloads our code every time we reload
a page, so our changes get picked up automatically.
The body attribute only appears in the list of all posts however,
it doesn't appear when you view a single post, so
let's go now the body attribute there as well.
When we request an individual post page and
then check our terminal, we'll see the log of Rails handling the request.
There we'll see rendering posts/show.html.erb,
so let's edit that file.
We'll go to app, views, posts show.html.erb.
Again it's already set up to show the post title, so let's copy that code and
modify it to show the post body as well.
I'll change the label to Body and
we'll change the ERB tag to access the body attribute.
By the way, notice that the instance variable in this view is named post,
since this is the view for a single post.
In the view for
the list of all posts the instance variable was named posts, plural instead.
We can actually set up whatever names we want in the controller and
we'll show you how to do that in an upcoming course.
But the convention is to use names like these when you're loading just one model.
So if we save our work and reload the page we'll see the post body.
When we edit an existing post or create a new post,
we're not given a field to edit the body attribute, let's fix that next.
When we request the edit page for a post,
we'll see Rendering posts/edit.html.erb within the log and
when we request that new post page.
We see rendering post new.html.erb in the log.
But when we edit the erb template in edit.html.erb,
we don't see HTML to render a form directly.
The same is true for the template in new.html.erp.
Instead in both these places,
we see a call to the render method with an argument of form.
Notice that the form to update an existing post looks identical to the form to add
a new post, that's because they're actually the same form.
Our form code is actually stored in one place, but it gets rendered in two views.
We do that using a partial, we'll look at partials next.
You need to sign up for Treehouse in order to download course files.Sign up