spitfire109
spitfire109

Reputation: 10029

Rails nested relationships in ActiveRecord

I would like to query for the sections that belong to schools with these models:

School
  has_many :terms

Term
  belongs_to :school
  has_many :departments

Department
  belongs_to :term
  has_many :courses

Courses
  belongs_to :department
  has_many :sections

Section
  belongs_to :course

I am a little bit lost as to how to do this.

I would like to be able to call a list of sections that belong to the school and find the school from the sections (and query for all the relationships in between)

Any help would be greatly appreciated.

Upvotes: 0

Views: 393

Answers (3)

nilay
nilay

Reputation: 365

In have to iterate through each model from top to bottom. For example:

s = School.find(1)
s.terms.find(1).departments.find(1).courses.find(1).sections  

This will give you the sections that are associated with school_id = 1

Since your model has cascading has many, you have to go like this unless you want to change your database schema..

Upvotes: 1

Dan Wich
Dan Wich

Reputation: 4943

To find the school from a section, you would just do:

section.course.department.term.school

If there aren't so many records as to slow this down, you can get an array of sections for a given school by doing:

sections = []
school.terms.each do |term|
   term.departments.each do |department|
      department.courses.each do |course|
         course.sections.each do |section|
            sections << section
         end
      end
   end
end

That will also give you access to each relationship in-between if you need to do any further processing.

And here's a terser version:

sections = school.terms.map(&:departments).flatten.map(&:courses).flatten.map(&:sections).flatten

Upvotes: 0

rocket scientist
rocket scientist

Reputation: 2447

If you are working with Rails 3.1 or above you can use :has_many :through to help you get the sections that are within each school. First, you need to set up your relations in your models:

School
  has_many :terms
  has_many :departments, :through => :terms

Term
  belongs_to :school
  has_many :departments

Department
  belongs_to :term
  has_many :courses
  has_many :sections, :through => :courses

Courses
  belongs_to :department
  has_many :sections

Section
  belongs_to :course

Then to get the sections for a school you can do...

School.first.departments.collect{|d| d.sections}.flatten!

To get the school that a section belongs to all you need to do is

section.course.department.term.school

Upvotes: 1

Related Questions