No table view after CRUD Scaffolding

Viewed 173

I'm currently learning about Ruby on Rails, following this particular tutorial https://www.youtube.com/watch?v=fmyvWz5TUWg&t=2625s

After execute the command rails g scaffold friends name:string email:string phone:string followed by rails db:migrate I ended up with a CRUD structure to that simple friend model (name, email and phone all strings).

Everything is good and all works fine except when i go to http://localhost:3000/friends and the list of friends is showed in a weird way! I was expecting a table where witch row is an friend, instead of that i end up with a vertical structure where each friend is displayed vertically...

index.html.erb

<p style="color: green"><%= notice %></p>

<h1>Friends</h1>

<div id="friends">
  <% @friends.each do |friend| %>
    <%= render friend %>
    <p>
      <%= link_to "Show this friend", friend %>
    </p>
  <% end %>
</div>

<%= link_to "New friend", new_friend_path %>

_friend.html.erb

<div id="<%= dom_id friend %>">
  <p>
    <strong>Name:</strong>
    <%= friend.name %>
  </p>

  <p>
    <strong>Email:</strong>
    <%= friend.email %>
  </p>

  <p>
    <strong>Phone:</strong>
    <%= friend.phone %>
  </p>

</div>

Illustrative image: enter image description here

I believe that i have something with wrong configuration but can't find out what.

All source code: https://github.com/Paul-Bob/RailsFriends

2 Answers

everything in your case is OK with backend - the only part that needs refinement is the frontend presentation of friends. I'm not sure what version of rails you are using - and what configuration settings - thus sometimes scaffolding can generate a table - sometimes just a simple view like yours.

In order to display friends in a table you have to implement a HTML table:

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @friends.each do |friend| %>
      <tr>
        <td><%= friend.name %></td>
        <td><%= friend.email %></td>
        <td><%= link_to 'Show', friend %></td>
        <td><%= link_to 'Edit', edit_friend_path(friend) %></td>
        <td><%= link_to 'Destroy', friend, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

I had the same problem and came across your question while looking for a solution. It appears that the Rails team made a decision to change the index template, though I don't know what the reason was. Possibly because a lot of people are going to want to define their own specific way for tables to be laid out.

Custom scaffolding templates

If you do want to use scaffolding, and don't want to have to change the generated index each time, you can create your own custom scaffolding templates.

Explanation of custom templates

This guy does a good job of explaining how to do this:

https://web-crunch.com/posts/how-to-create-custom-scaffold-templates-in-ruby-on-rails

Default templates

You may want to look at the default templates as a reference. You can find these in your Rails installation. I'm running on Windows, so for me, they are found in:

C:\Ruby31-x64\lib\ruby\gems\3.1.0\gems\railties-7.0.3.1\lib\rails\generators\erb\scaffold\templates

The folder structure will be similar on every platform.

Default templates on GitHub

You can also look at the source on GitHub. Found here:

https://github.com/rails/rails/tree/main/railties/lib/rails/generators/erb/scaffold/templates

If you look at "index.html.erb.tt" specifically, you can go into the history and look at where it changed from being rendered as a table. It looks like the change to "modernize" the template happened 4 Feb 2021. If you look at the version before that, you should have something that can generate a table.

Another tutorial

Here's another example, which generates templates that use Bootstrap and Simple Form. I found it quite a good fit as I was already using Bootstrap and just had to add Simple Form to my Gemfile:

gem 'simple_form'

Regenerating scaffold

After getting the templates from the above example, I wanted to use them to regenerate my views. This can be done with:

rails g erb:scaffold friend first_name last_name phone twitter

Disclaimer

I literally looked at Ruby for the first time yesterday, so this answer may need some editing. :)

Related