locoboy
locoboy

Reputation: 38960

Dynamically load content in dynamically generated tabs in bootstrap rails

I'm dynamically generating tabs in bootstrap and rails per the code below:

<ul class="nav nav-tabs" role="tablist" id="tabs">
  <% @exercises.each_index do |i| %>
    <% if i == 0 %>
      <li class="active"><a href="#<%= @exercises[i].name.downcase %>" data-toggle="tab" aria-controls="<%= @exercises[i].name.downcase %>"><%= @exercises[i].name %></a></li>
    <% else %>
      <li><a href="#<%= @exercises[i].name.downcase %>" data-toggle="tab" aria-controls="<%= @exercises[i].name.downcase %>"><%= @exercises[i].name %></a></li>
    <% end %>
  <% end %>
</ul>

<div class="tab-content">
  <% @exercises.each_index do |i| %>
    <% if i == 0 %>
      <div class="tab-pane active" id="<%= @exercises[i].name.downcase %>">
        First tab
      </div>
    <% else %>
      <div class="tab-pane" id="<%= @exercises[i].name.downcase %>">
        Other tab
      </div>
    <% end %>
  <% end %>
</div>

The problem is that @exercises will vary from user to user and is not preset. Since it's not preset, I need to generate the appropriate content depending on what's returned. First tab and Other tab needs to be replaced by content specific to the user and the exercise.

Is there a clean way of doing this?

Upvotes: 1

Views: 1096

Answers (1)

6ft Dan
6ft Dan

Reputation: 2445

It's best if the exercises belong_to User.

In the User model add has_many :exercises and in the Exercise model add belongs_to :user. The Exercise Object should have a user_id field to reference what user owns it. Then you can call your user with all exercises by user.exercises. If you're using devise it will be current_user.exercises

With add the changes you will get the following. Oh, and you can get rid of the if/else clutter by just adding if to the <li> HTML tag for class="active".

<% @exercises = current_user.exercises %>
<ul class="nav nav-tabs" role="tablist" id="tabs">
  <% @exercises.each_index do |i| %>
      <li <%= 'class="active"' if i == 0 %>><a href="#<%= @exercises[i].name.downcase %>" data-toggle="tab" aria-controls="<%= @exercises[i].name.downcase %>"><%= @exercises[i].name %></a></li>
  <% end %>
</ul>

<div class="tab-content">
  <% @exercises.each_index do |i| %>
      <div class="tab-pane <%= 'active' if i == 0 %>" id="<%= @exercises[i].name.downcase %>">
        Tab Content
      </div>
  <% end %>
</div>

Same results, much less code.

You can also accomplish the each exercise loop without using index and change the if statement as follows:

<% @exercises.each do |ex| %>
  <div class="tab-pane <%= 'active' if @exercises.first == ex %>" id="<%= ex.name.downcase %>">
    Tab Content
  </div>
<% end %>

Or with each instance and index

<% @exercises.each.with_index do |ex, i| %>
  <div class="tab-pane <%= 'active' if i == 0 %>" id="<%= ex.name.downcase %>">
    Tab Content
  </div>
<% end %>

For Tab Content you simply need to know what fields you're using from which traits. Depending on what you have it could be.

Name is <%= current_user.name %>
Email is <%= current_user.email %>
Exercise is <%= exercise.name %>
Exercise time is <%= exercise.workout_length %>
Exercise reps are <%= exercise.reps %>

It really depends on your model and the fields you have available.

Upvotes: 1

Related Questions