Re: [Modeling-users] Re: attaching information to a relation
Status: Abandoned
Brought to you by:
sbigaret
|
From: Sebastien B. <sbi...@us...> - 2003-08-04 22:00:34
|
Hi Mario,
Mario Ruggier <ma...@ru...> wrote:
> On Lundi, ao=FB 4, 2003, at 20:49, Sebastien Bigaret wrote:
> > Mario wrote:
> >> just wondering how this can be best done... as a simple example,
> >> assume a Person and an Address tables. A Person may have
> >> more than one address, but each address may be categorized
> >> as being "primary", "secondary", "private", "work", or anything
> >> a priori unknown, Where does one best stick this information?
> >
> > I think this is what uml calls a "qualified association".
>=20
> Thanks for the explanation(s) below...
> This would work just fine, if an Address belongs (exclusively)
> to any one Person. What I am looking for is a way to reuse
> the same Address for different people, but the type of
> relation may be different each time. E.g.
>=20
> Mr. Dough's lives in a Villa, across from the beach (private Address)
> Ladi Lean is the housemaid for Mr. Dough (work Address)
> Mr. Dough's little sister spends summers at his villa (secondary Address)
> ...
>=20
> The most natural thing to me would be to add a "property"
> to the association, if that'd be allowed. I guess one would have
> to make an addditional association table for this?
Okay, I didn't understand you properly. Now it's clear, you need
qualified many-to-many associations. Here is a draft guideline for
modeling a many-to-many relationship:
- create entity PersonAdress --yes, this is the correlation table,
- add attribute 'category' to it
- add a to-many relationship from Person to PersonAdress, and its
inverse (to-one): Person <---->> PersonAdress
- add the two relationships: PersonAdress <<-------> Address
- in Person, then add a method for getting addresses:
def getAddresses(self, type=3DNone):
if type is None:
return self.valueForKeyPath('toPersonAddresses.toAddress')
else:
PAs=3D[pa for pa in self.getPersonAddresses() if pa.getType()=3D=
=3Dtype]
addrs=3D[]
[addrs.extend(pa.getPerson()) for pa in PAs]
return addrs
- add a similar one in Address if you need the inverse (from Address
to Person),
- be careful about setters, you need to manipulate the intermediate
object, something like this:
def addToAddresses(self, address, type):
# you may also want to check that it's not already added
# under an other category, or under the same category
_pa=3DPersonAddress(type=3Dtype)
self.editingContext().insert(_pa)
self.addToPersonAddresses(_pa)
_pa.setPerson(self)
_pa.setAddress(address)
address.addToPersonAddresses(_pa)
def removeFromAddresses(self, address, type=3DNone):
_pa=3D[pa in self.getPersonAddresses() if address =3D=3D pa.getAdd=
ress()]
if type:
_pa=3D[pa in _pa if pa.getType() =3D=3D type]
if not _pa:
raise ValueError, 'Cannot find address'
# here you can get one or more PersonAddress, depending on
# whether you allow the same Address to be registered under a
# single category or not
_pa=3D_pa[0] #or iterate on all, which could be handy if you want
#to remove all relations to 'address' when type=3D=3DNo=
ne
self.removeFromPersonAddresses(_pa)
_pa.getAddress().removeFromPersonAddresses(_pa)
_pa.setAddress(None)
_pa.setPerson(None)
self.editingContext().remove(_pa)
I didn't try it, though ;) I may create a special unittest suite for
this, and use it to document many-to-many... If you try this, I'd like
to hear from you, and I'll try to help to my best if have any problem.
Cheers,
-- S=E9bastien.
|