[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

RoR has_and_belongs_to_many association

Esteban Manchado Velázquez

4/22/2005 11:25:00 PM

Hi all,

I'm writing a small RoR application to make a presentation (I'll publish
the LaTeX/PDF slides and the app, but in Spanish), and I'm using the
has_and_belongs_to_many association.

I have this:

- Table A and table B, associated with h_a_b_t_m
- Table A_b with _additional fields_ (a_id, b_id, foo and bar)

The question is, how can I update the "foo" and "bar" values? When I call
a.bs, I can read the values of those fields, but updating doesn't seem to
work. It doesn't raise any exception, but doesn't update the database either.
What am I doing wrong? Is there any easy way to update the "foo" and "bar"
fields?

Regards,

--
Esteban Manchado Velázquez <zoso@foton.es> - http://ww...
EuropeSwPatentFree - http://EuropeSwPatentFree.his...


3 Answers

threeve.org

4/23/2005 5:28:00 PM

0

On 4/22/05, Esteban Manchado Velázquez <zoso@foton.es> wrote:
> Hi all,
>
> I'm writing a small RoR application to make a presentation (I'll publish
> the LaTeX/PDF slides and the app, but in Spanish), and I'm using the
> has_and_belongs_to_many association.
>
> I have this:
>
> - Table A and table B, associated with h_a_b_t_m
> - Table A_b with _additional fields_ (a_id, b_id, foo and bar)
>
> The question is, how can I update the "foo" and "bar" values? When I call
> a.bs, I can read the values of those fields, but updating doesn't seem to
> work. It doesn't raise any exception, but doesn't update the database either.
> What am I doing wrong? Is there any easy way to update the "foo" and "bar"
> fields?
>

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.

class C < ActiveRecord::Base
belongs_to :a;
belongs_to :b;
# add your foo, bar attributes to this table.
end


Jason



Esteban Manchado Velázquez

4/23/2005 6:32:00 PM

0

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 <ActiveRecord::Base
has_and_belongs_to_many :cursos
end

class Curso <ActiveRecord::Base
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.

> 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.

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)?

TIA. Regards,

--
Esteban Manchado Velázquez <zoso@foton.es> - http://ww...
EuropeSwPatentFree - http://EuropeSwPatentFree.his...


threeve.org

4/25/2005 12:24:00 AM

0

On 4/23/05, Esteban Manchado Velázquez <zoso@foton.es> 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 <ActiveRecord::Base
> has_and_belongs_to_many :cursos
> end
>
> class Curso <ActiveRecord::Base
> 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