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