I am a Rails newbie so I don't have a clear idea on how to approach this problem.
I have an ActiveRecord::Associations::CollectionProxy
object stored in @electives
. Specifically, I have
@electives = @degree.electives
Degree
and Elective
are models with tables degrees
and electives
. I have defined a has_and_belongs_to_many
association between Degree
and Elective
models.
Additionally, I also have a Course
model with a corresponding courses
table. I have also defined another has_and_belongs_to_many
association between Course
and Elective
models.
In addition to the above listed tables, I also have degrees_electives
and courses_electives
join tables.
Now, I want to display on a page, a list of Electives in a Degree, and all the Courses associated to an Elective. So, I want something like:
- Software Engineering Elective A
- COMP SCI 3008 Computer Networks & Applications
- COMP SCI 1234 Object Oriented Programming
- COMP SCI 4567 Algorithm Design & Data Structure Analysis
- Software Engineering Elective B
- MATHS 1012 Mathematics IA
- CIVIL 2000 Civil Engineering Introduction
- Software Engineering Elective C
- COMP SCI 1012 Introduction to Programming
I am able to display the list:
- Software Engineering Elective A
- Software Engineering Elective B
- Software Engineering Elective C
But I don't know how to display the sub-list.
Currently, I have in my controller:
@degree = @student.degrees.first
@electives = @degree.electives
@degree
contains a Degree
object.
And, my view contains:
<ul>
<% @electives.each do |elective| %>
<li>
<%= elective.name %>
</li>
<% end %>
</ul>
The webpage looks like this:
I would like help with displaying the sub-list.
What I am stuck at is, how should I store the list and make it available to the view, when I call .courses
on each element of @electives
. For example, I could do:
@electives.each do |elective|
@courses = elective.courses
end
But then, @courses
will contain courses that correspond with the last element of @electives
, if and when I use @courses
in the view.
Is there like a vector data structure available in Ruby that I can push values to? I don't know how to do this. Any help will be very much appreciated. Thank you.
CodePudding user response:
You can iterate over courses that are associated with an elective in the same way as you already iterate over the courses with the only difference to do it nested within the other iteration:
<ul>
<% @electives.each do |elective| %>
<li><%= elective.name %>
<ul>
<% elective.courses.each do |course| %>
<li><%= course.name %></li>
<% end %>
</ul>
</li>
<% end %>
</ul>
To avoid a N 1 queries problem I suggest eager loading all courses that are associated with the electives in one query by changing your controller to:
@degree = @student.degrees.first
@electives = @degree.electives.includes(:courses)
CodePudding user response:
You don't even need variable
<ul>
<% @electives.each do |elective| %>
<li>
<%= elective.name %>
<ul>
<% @elective.courses.each do |course|%>
<li>
<%= course.name %>
</li>
<% end %>
</li>
<% end %>
</ul>
In controller you better include elective with course to have it initialized, to not have n*m calls to database
@electives = Elective.includes(:courses)