On Tue, Nov 10, 2009 at 2:16 PM, Naftoli Gugenheim <naftoli...@gmail.com>wrote:
> Hello. > When I wrote ManyToMany a couple of months ago, I designed it to internally > hold a collection of join table records, and to act as a collection of > elements of the child table. > For example, given Volunteer and VolunteerGroup where volunteers can be in > multiple groups, Volunteer.volunteerGroups implements a collection of > VolunteerGroups, but internally it's actually managing a collection of > VolunteerVolunteerGroups (the join table). > I don't think you really need to maintain the pivot table list (VolunteerVolunteerGroups) at all. If you maintain the Many-to-Many as part of the object, and use a standard naming convention then you don't really need this extra list running around. You can still build the SQL correctly knowing only the objects involved. > The current implementation throws an error (Predef.error) when it tries to > get the child element via the join record and it doesn't exist. Thus any > page accessing corrupted data will not display if the error is not caught. I > plan, G-d willing, to change the implementation to silently skip such > records. > But the occurrence that reminded me of the defect also brought another > point to my attention. To my knowledge Lift's schemifier does not correctly > generate foreign key constraints for all databases (at least not at the > point in time it schemified my H2 database... :) ) so we need a way for > ManyToMany to keep things in sync. ManyToMany helps, to an extent, because > when its MappedManyToMany members are initialized, it puts them in a list, > and it propagates saves and deletes. So if you have a ManyToMany Mapper > instance that contains a MappedManyToMany that has been initialized, and you > call delete_! on the Mapper, it will delete all the associated join table > entries. But it's not enough. > > 1. That can only happen if both sides of the relationship use > MappedManyToMany. Is there some way to enforce this? I was thinking of > using > a combination of (a) requiring the foreign MetaMapper to extends > ManyToMany, > and (b) when a MappedManyToMany is initialized, it should check that the > foreign MetaMapper/ManyToMany actually contains a MappedManyToMany > referring > to the current MappedManyToMany. (a) is not sufficient without (b), and (b) > has the same problem as #2 below, that objects are lazy. > > I think you're right here. Both sides have to have the mapping.. however I don't think there is a good clean way to detect this without a compiler plugin of some kind. > > 1. There is a basic problem, which is that since objects are lazy, if > you haven't referenced the MappedManyToMany field, delete_! will not be > able > to propagate to the join entries. > > As you traverse the deleteing side, doesn't the other side get initialized as well? > #2 and #1.b can be solved by using reflection to initialize the > MappedManyToMany members eagerly, just as MetaMapper does for all > MappedFields. (MappedManyToMany is not a MappedField.) Now the advantage to > having them lazy is that if you don't reference them they don't query the > database. This advantage can be retained though by implementing the > collection internally to populate lazily, much as MappedOneToMany already > is. > > Thoughts? > I think your maintaining to much information that can be deduced from the context. > > Thanks, > Naftoli Gugenheim > > > > > > -- James A Barrows --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~----------~----~----~----~------~----~------~--~---