Reputation: 1370
I'm struggling to display only the RELEVANT data in a table that is using has_many and through relationships. My models are the following:
class TrainingResource
has_many :user_training_resources, dependent: :destroy
end
class UserTrainingResource
belongs_to :user
belongs_to :training_resource
end
class Users
has_many :user_training_resources, dependent: :destroy
has_many :training_resources, through: :user_training_resources
end
Ultimately I'm trying to build out a table on the Training Resource Show page of those users that have THAT Training Resource and their current status along with the ability for the user to delete said resource (User Training Resource).
So example while looking at Alpha Training Resource the user sees of the Training Resource: Name, Description, URL, and Total Subscriptions. Then below a list of the users that have Alpha Training along with their current status AND the option to delete it.
class Admin::TrainingResourcesController < Admin::ApplicationController
belongs_to_app :training_resources
add_breadcrumb 'Training Resources', :admin_training_resources_path
before_action :load_training_resource, only: [:show, :edit, :update, :destroy]
respond_to :html, :json
def show
@user_training_resources = UserTrainingResource.all
@users = User.all
respond_with(@training_resource)
end
private
def load_training_resource
@training_resource = TrainingResource.find_by!(id: params[:id])
end
end
My Training Resource Show template looks like:
<dl class="dl-horizontal">
<dt>Name:</dt>
<dd><%= @training_resource.name %></dd>
<dt>Description:</dt>
<dd><%= @training_resource.description %></dd>
<dt>Subscriptions Available:</dt>
<dd><%= @training_resource.subscriptions_available %></dd>
<dt>Total Subscriptions:</dt>
<dd><%= @training_resource.total_subscriptions %></dd>
<dt>Url:</dt>
<dd><%= @training_resource.url %></dd>
</dl>
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Training Resource Names</th>
<th>Status</th>
<th> </th>
</tr>
</thead>
<tbody>
<% @users.all.each do |user| %>
<tr>
<td><%= user.full_name %></td>
<td><%= user.training_resources.map(&:name).join(', ') %></td>
<td><% user.user_training_resources.each do |user_training_resource| %></td>
<td><%= user_training_resource.status %></td>
<% end %>
<td class="table-actions">
<%# <%= link_to 'Delete', admin_user_training_resource_path(@user_training_resource), :method => :delete, :data => {:confirm => 'Are you sure you want to delete this Training resource?'}, :class => 'btn btn-danger btn-sm' %> %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
So if I go to Training Resource and click on the show for Alpha I see it's name, description, total subscriptions, and url. However the table below will show me all users, all their training resources, and then their status. Not exactly what I want.
I've tried doing something like below in hopes of just going through Training Resource:
<% @training_resource.each do |training_res| %>
<%= training_res.name %>
<% end %>
This results in undefined method 'each'. So how do I display ONLY the data associated with the TrainingResource?
Upvotes: 0
Views: 26
Reputation: 4920
Add a new association for users
in model TrainingResource
, so that you can directly fetch all the users for a training_resource record.
class TrainingResource
has_many :user_training_resources, dependent: :destroy
has_many :users, through: :user_training_resources
end
Change your controller action show
to look like below:
def show
respond_with @training_resource
end
And display the users inside <tbody>
tag on training_resource show page in the following way:
<% @training_resource.users.each do |user| %>
<tr>
<td><%= user.full_name %></td>
<!-- If you want to display all the training_resources of the user and their statuses -->
<td><%= user.training_resources.map(&:name).join(', ') %></td>
<td><%= user.user_training_resources.map(&:status).join(', ')</td>
<td class="table-actions">
<!-- Assuming your path is something like '/admin/training_resources/:id/users/:user_id' -->
<%= link_to 'Delete', admin_user_training_resource_path(@training_resource, user), method: :delete, data: { confirm: 'Are you sure you want to delete this Training resource?' }, class: 'btn btn-danger btn-sm' %>
</td>
</tr>
<% end %>
This code is not tested. So, please let me know, if you face any errors.
Update
If you want to show the status of only the current training_resource for all the users, do:
<%- utr = user.user_training_resources.where(training_resource: @training_resource).first %>
<td><%= utr.status %></td>
Upvotes: 1