سؤال

In my application, I am grouping my objects by an ID. At the moment, I can only display the ID, but I would like to display the attribute value.

A Fixture belongs_to a tournament and a tournament has_many fixtures.

Controller

def index
  @fixtures = Fixture.all
  @tournament_fixture = @fixtures.group_by {|f| f.tournament_id}
end

View

<% @tournament_fixture.sort.each do |tourn_name, fixture| %>
     <%= tourn_name %>
        <% fixture.each do |f| %>
          <td><%= f.home_team %></td>
          <td><%= f.away_team %></td>
          <td><%= f.kickoff_time %></td>
        </tr>
        <% end %>
 <% end %>

How can I get

<%= tourn_name %>

to display its corresponding value that is in its :name column?

At the moment in my view for example i get this returned

<tbody>
        2
        <tr>
          <td>Tournament Name</td>
          <td>Team 1</td>
          <td>Team 2</td>
          <td>2000-01-01 14:00:00 UTC</td>
          <td><a class="btn btn-success" href="/fixtures/1">view</a></td>
        </tr>
      </tbody>

The 2 needs to be the value in the :name column

هل كانت مفيدة؟

المحلول

I'd recommend grouping by tournament instead:

@tournament_fixture = @fixtures.group_by(&:tournament)

And then iterate using:

<% @tournament_fixture.sort.each do |tournament, fixture| %>
  <%= tournament.name %>
  ...
<% end %>

نصائح أخرى

You can access the whole object much like you can get the id like this:

def index
  @fixtures = Fixture.includes(:tournaments).all
  @tournament_fixture = @fixtures.group_by {|f| f.tournament.name}
end

The id is still available as either f.tournament_id or f.tournament.id, should you still need it but I just figured you'd rather group by its name directly. I simply added an includes statement to also load the referenced Tournament objects with your fixtures in one go. Otherwise, Rails would load the tournaments only when you access them one by one.

As an alternative, you could load the Tournaments, including all their the fixtures instead and iterate over the tournaments like this:

Controller

def index
  @tournaments = Tournament.includes(:fixtures).all
end

View

<% @tournaments.each do |tournament| %>
  <%= tournament.name %>
    <% tournament.fixtures.each do |f| %>
      <td><%= f.home_team %></td>
      <td><%= f.away_team %></td>
      <td><%= f.kickoff_time %></td>
    </tr>
    <% end %>
<% end %>

It seems a bit more natural to me and you don't need to iterate over all fixtures to map them by their tournament.

You can load the fixtures in the right order. There is no need to group then in memory. Remember to include the tournaments to avoid N+1 queries.

# controller
def index
  @fixtures = Fixture.order(:tournament_id).includes(:tournaments).all
end

Loading in the right order in the controller makes the view simpler. For the tournament's name just use the association between Fixture and Tournament.

# view
<% @fixtures.each do |fixture| %>
  <tr>
    <td><%= fixture.tournament.name %></td>
    <td><%= fixture.home_team %></td>
    <td><%= fixture.away_team %></td>
    <td><%= fixture.kickoff_time %></td>
  </tr>
<% end %>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top