Beginner Problems with many-to-many Relations

Hello people!

I'm quite new to Rails and I've got a project to do that requires some many-to-many relations right at the beginning. I'll describe what I want to do, maybe you could tell me how to realize that.

I have the tables »people« and »courses«. One course can have multiple people (I'm talking of teachers here) and one person can be in multiple courses. As I started creating my application in the RESTful way and I learned that the »has_and_belongs_to_many« association doesn't work very well with the REST-approach, I created a third table and model called »teachers« that is the join model between those two, so the models look like this:

class Course < ActiveRecord::Base   has_many :teachers   has_many :people, :through => :teachers end

class Person < ActiveRecord::Base   has_many :teachers   has_many :courses, :through => :teachers end

class Teacher < ActiveRecord::Base   belongs_to :course   belongs_to :person end

Now following the RESTful way I should add teachers only through my »TeachersController«, right? Now what I'd like to do is the following.

When you are creating a new course, then on the same page with the course form (so /courses/new ) there should be the possibility to add people as teachers to the course. Then if you edit this course afterwords it should show you the teachers of this course and make it possible to get them out of this course and add new ones to the course. But how can I have that on the same page as the courses? How do I create a new teacher on the same page where the new or edit form of a specific course is?

I have really no clue. I mean I don't insist on having the »Add Teacher« thing on the new course page, but what I don't want, is to put it on an own page only for adding a teacher.

Would be very happy about some answers. :slight_smile:

It is very simple: REST is simply a guide to a good way to structure your program (especially useful for machine to machine communication)… I would suggest you go ahead and create the TeachersController and allow teachers to be added/edited/etc from that controller, because at some point you may want the ability to modify the Teachers stuff directly: if you add any extra properties to the Teachers association beyond just being a cross reference for the course - person relationship.

However, I agree that adding a teacher spot to your course controller seems like a reasonable idea, and it is very easy… although, you should realize, what you really want to do is add a Person to your Course, which you’re doing through your Teacher association. So what you might do is add a couple of text fields to your form where you could enter a Person’s name, then do something like this in the action you are submitting to:

c = Course.create(params[:course]) c.people << Person.find_by_name(params[:teacher_name]) c.save

This will automatically create the Teacher association for you. :slight_smile:

Your model has not captured the concepts in the domain properly. Student can have many teachers. Teacher can have many students. Each link that connects the Student to Teacher is through a Course. Course breaks up the many to many relationship.

You will know that your design is right when you have two entities that is connected by an association descriptive table. For instance, you will have Subscription for the entities People and Magazine, InsurancePolicy for People and Insurance, Marriage for Man and Woman and so on. This is due to the fact that we are promoting an association class to a regular class. An association class describes the relationship between two entities. It holds information that does not belong to either of the entity that it connects. So InsurancePolicy will have renewal date and this date does not logically belong to Person or Insurance. The data comes alive only when the connection between the entitities is established.

Remember that habm relationship is sufficient if your domain requires only a simple join table. You have to pick the right solution for the problem. If you need to capture more than just the foreign keys in the join table then you need to use :through style declaration.

Yes, there is almost one-to-one correspondence between your model classes and controllers.

Now you got a better idea of how to design your object model, you can go back and think about to represent them in your views.