From: Jason Foreman Date: 2005-04-25T09:24:04+09:00 Subject: Re: RoR has_and_belongs_to_many association On 4/23/05, Esteban Manchado Vel�zquez wrote: > Hi Jason, > > Thanks for your answer. Some more details below: > > On Sun, Apr 24, 2005 at 02:27:57AM +0900, Jason Foreman wrote: > > [...] > > Many times a many-many relationship like this is really another piece > > of your model that you need to work with, particularly when you have > > additional information associated with the relationship. You might > > need to add a model C which represents the relationship of a<->b and > > contains those additional attributes. You haven't given any details > > as to what your A and B are, so I can't give you any insight into what > > the relationship model might be, but consider modelling it as its own > > class. > > Sorry, I thought it wasn't necessary, and as the code is written in Spanish > (for the RoR presentation), I didn't feel like translating :-) > > The main idea is having pupils and classes. You have a pupils table/model > (alumnos) and a classes table/model (cursos). So I have: > > class Alumno has_and_belongs_to_many :cursos > end > > class Curso has_and_belongs_to_many :alumnos > end > > and I have two additional fields in the "alumnos_cursos" table, "reservado" > and "pagado" ("reserved" and "paid"). So, when someone goes and pays some > class, in the code I need to update the "pagado" field in "alumnos_cursos" so > it's not NULL anymore. I'd perhaps generate a new model called Registration (sorry, don't know the Spanish equivalent). A registration can reference the pupil and the course and have the reserved and paid fields. This would allow you to query registrations based on pupil or course or both. class Registration < ActiveRecord::Base belongs_to :alumnos belongs_to :cursos end class Cursos < ActiveRecord::Base has_many :registrations end class Alumnos < ActiveRecord::Base has_many :registrations end > > > class C < ActiveRecord::Base > > belongs_to :a; > > belongs_to :b; > > # add your foo, bar attributes to this table. > > end > > Hmmm... what about the "id" attribute? I know I can't simply put one, as it > would clobber the alumnos or cursos one when using the h_a_b_t_m relation. Well, in RoR, I think you need to have a separate id field. Then you could put a unique constraint on the (alumnos_id, cursos_id) fields to make sure each pupil only registers for a course once. > > And, how can i find a particular relation in this table? Should I just > "find_all(:a_id => x, :b_id => y).first", or is there any way to obtain that > object from the has_and_belongs_to_many association (I mean something like > "alumno.cursos.first.relation" to get a AlumnosCursos class)? There are several ways to do this. Knowing the id of the Alumnos or Cursos, you can simply use find_by_sql and add these into the where clause. Or you could use the relationships to get all cursos for a given alumnos (or vice versa) and then use Ruby to select certain ones. Or you could get all Registratrions and work with the associations there. Your options are many. > > TIA. Regards, > NP. Hope that I was able to help in some way. Jason