Search code examples
ruby-on-railshas-and-belongs-to-many

Has and belongs to many - display all records in table view


I have a model called Patient and table patients

This model Patient represents a patient in a doctor's office.

I have a model for gender populated with different gender names

Patient has_and_belongs_to_many :genders and Gender has_and_belongs_to_many :patients.

I have a similar implementation for race, concerns, insurances.

In a Patients index view I'm trying to show a given patients race or races, concern or concerns, insurance or insurances (they could have none, 1, or many). How can I show all of them all at once? The only way I have been able to figure out to show any is to call first.name as seen below. Thanks!

<table>
  <tr>
      <th>Patient ID</th>
      <th>Created</th>
      <th>Created By</th>
      <th>Staff Clinician</th>
      <th>Concerns</th>
      <th>Gender</th>
      <th>Race</th>
      <th>Insurance</th>
      <th>Referral Request</th>
  </tr>

<% @patients.each do |patient| %>
  <tr>
    <td><%= patient.id %></td>
    <td><%= patient.created_at.strftime("%Y-%m-%d") %></td>
    <td><%= patient.user_id %></td>
    <td><%= patient.staff_clinician_id %></td>
    <td><%= patient.concerns.first.name %></td>
    <td><%= patient.genders.first.name %></td>
    <td><%= patient.races.first.name %></td>
    <td><%= patient.insurances.first.name %></td>
    <td><%= link_to "Show", patient %></td>
    <td><%= link_to "Edit", edit_patient_path(patient) %></td>
    <td><%= link_to "Remove", patient, method: :delete, data: { confirm: "Are you sure?" } %></td>
  </tr>
<% end %>
</table>

Solution

  • You can use to_sentence over the collections.

    <td><%= patient.concerns.map(&:name).to_sentence %></td>

    or

    <td><%= patient.concerns.map{ |concern| concern.name&.titleize }.to_sentence %></td>

    The & is for safe navigation, meaning if the concern does not have a name then the following .titleize won't blow up.

    Anyway, this approach of displaying the collection is nice when working with tables because only need one cell to display everything.