0

I am trying to create the following basic structure with RoR. The key is that all Users also be linked to a School and a Major. Users will write articles based on their School and Major. The linking is not exclusive: many users can be in one of many schools, and one of many majors. However, each user cannot be in more than one school, and cannot be in more than one major. Eventually, I would like to be able to show posts/filter articles based on the following:

  • All Users in both Major X and at School Y
  • All Majors at School Y
  • All Schools with Major X

I've done a little research, not sure if any of this is correct... (still learning) should I be using has_and_belongs_to_many below as compared to has_many?

Table

major_schools #(linking the two models below)

Models

class School < ActiveRecord::Base
  has_many :major_schools
  has_many :majors, :through => :major_schools
end

class Major < ActiveRecord::Base
  has_many :major_schools
  has_many :schools, :through => major_schools
end



@school.majors #now gives a list of all the majors this school has
@major.schools #still gives a list of all schools that have this major

What I need to do is also incorporate a user model with the two above:

class User < ActiveRecord::Base

  has_and_belongs_to_many :major_schools

end

And I am quite stuck... How can I pull in the User model data to the above models?

tereško
  • 58,060
  • 25
  • 98
  • 150
Caroline
  • 104
  • 1
  • 10
  • 1
    Can majors be a part of more than one school? That doesn't seem right. – Shane Sep 20 '13 at 23:19
  • Shane, yes - for example, "Web Design" major or "History" major or "Fashion" major or "Advertising and Marketing" major - they are not exclusive to the school – Caroline Sep 20 '13 at 23:23

2 Answers2

1

Your domain model is a tad tangled here, but it works.

Here is one way to load all Users in both Major with id X and at School with id Y:

class MajorSchool < ActiveRecord::Base
   belongs_to :major
   belongs_to :school

   has_and_belongs_to_many :users
end

# Load all users from this school/major combination
MajorSchool.where(major_id: X, school_id: Y).users
Shane
  • 514
  • 3
  • 6
1

Why not simply do:

class School < ActiveRecord::Base
  has_many :major_schools
  has_many :majors, :through => :major_schools
  has_many :users
end

class Major < ActiveRecord::Base
  has_many :major_schools
  has_many :schools, :through => major_schools
  has_many :users
end

class User < ActiveRecord::Base
  belongs_to :school
  belongs_to :major
end

Then you should be able to do:

# all students of the school
@school.users

# all students of the school and major (each line should return the same results)
@school.users.where(major_id: @major.id)
@major.users.where(school_id: @school.id)
User.where(school_id: @school.id, major_id: @major.id)
Jakub K
  • 1,713
  • 1
  • 13
  • 21
  • Thank you jacovac. Question, why would it not be appropriate to use has_and_belongs_to_many :users (for the last has_many :users)? – Caroline Sep 21 '13 at 00:17
  • 1
    What you want to define, according to your question, is that each one model School has many models Users, and each one model User belongs to one School. `has_and_belongs_to_many` is used as a shorthand for _m to n_ associations. So you could replace first two has_many in your School and Major models with it if you don't want any extra models. More info in the [guide](http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many). – Jakub K Sep 21 '13 at 05:48