- Read Tutorial
- Watch Guide Video
In this guide we're going to refactor the application's index action to conform with Rails best practices.
It's considered a Rails antipattern to have the full loop code inside the <tbody>
tag, so we are going to create a new file called _post.html.erb
in the views/posts
folder. Make sure to stick to this naming convention as this refactor will not work if you name the file anything else.
Now grab the loop code from index.html.erb
and paste it in _post.html.erb
, just like this:
<!-- app/views/posts/_post.html.erb --> <tr> <td> <%= post.id %> </td> <td> <%= post.date %> </td> <td> <%= post.user.last_name %> </td> <td> <%= truncate(post.rationale) %> </td> </tr>
To call this partial we'll need to update the index.html.erb
file, add the code where the loop previously was:
<!-- app/views/posts/index.html.erb --> <%= render @posts %>
Rails is intelligent enough to know that when it encounters this line, it has to look for code inside a file called _post.html.erb
. This is why the naming convention is so important here.
If you refresh your browser, you'll see that nothing has changed and the application is working properly.
Next, let's run rspec
.
There's a failure, and it says that last_name
doesn't exist. If you go to post_spec.rb
, you'll see that there is no user_id
in the posts that we created. Let's add that.
# spec/features/post_spec.rb it 'has a list of posts' do post1 = Post.create(date: Date.today, rationale: "Post1", user_id: @user.id) post2 = Post.create(date: Date.today, rationale: "Post2", user_id: @user.id) visit posts_path expect(page).to have_content(/Post1|Post2/) end
Now, when you run rspec
, everything should work fine.