[prev] [thread] [next] [Date index for 2005/10/27]
This is a multi-part message in MIME format. --===============1154549139== Content-class: urn:content-classes:message Content-Type: multipart/alternative; boundary="----_=_NextPart_001_01C5DACC.BE3F2593" This is a multi-part message in MIME format. ------_=_NextPart_001_01C5DACC.BE3F2593 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable > Peter Speltz [peterspeltz@xxxxx.xxx] wrote: > What i have seen a lot is is the use or "delete_all" on the results > from a search. > $class->search( id =3D> $related_id)->delete_all; > and if a "my_method" is a has_many accessor i think you can say; > $self->my_method(id =3D> $id)->delete_all; Unfortunately this does not work - it returns the mapped objects = themselves. Thus, using this code you end up deleting both the entry in your lookup table *and* = the the record for the mapped object. > I'm not sure if has_many method will return an iterator in scalar > context or not. In scalar context it is an iterator, in list context a list of the = proper objects. > Bill Moseley [moseley@xxxx.xxx] wrote: > The use where I needed something like this is when updating, say, a > user form where there's collection of checkboxes for "Roles" which = are > maintained in a many_to_many table. This is exactly my scenario - the tables (simplified) are: table USER with columns 'id', 'name' table USER_GROUP_MAP with columns 'user_id', 'group_id' table GROUP with columns 'id', 'name' The method containing the mapping information is called 'mapped_groups'. The code snippet Bill provided (see below) does the right thing - and I = did it more or less in the same but a non-generic way by providing an = extra sub in my USER class. The thing I do not really like about Bill's = code is the need to dig into the object's hash structure - because there = is no method available to retrieve the necessary information. I'd rather = have a somewhat 'cleaner' way of deleting the mapping data. That said I think it'd be very nice to have something like these = 'add_to_XXX' (in this case: 'add_to_mapped_groups') methods for = removing the mapping information like: $user -> delete_from_mapped_groups(@group_objects_to_be_deleted); I believe that CDBI should have all the necessary information internally = to be able to dynamically create something like this? Correct me if I am = wrong (I have not had a detailed look at the CDBI's internals). WDL ---------------- Bill's code: >BTW -- I'm not that clear on what the "mapping" array can hold -- seem >like it's always a one element array. > # here, $class is "User" and $field->name is "roles" > > $meta =3D $class->meta_info('has_many')->{$field->name}; > > # Grab the value from the form field > my $value =3D $field->value; > > # Figure out which values to keep: > > my %keep =3D map { $_ =3D> 1 } ref $value ? @$value : ( $value = ); > > # Get foreign class and its key that points to $class > my $foreign_class =3D $meta->foreign_class; # Mapping class > my $foreign_key =3D $meta->args->{foreign_key}; > my $related_key =3D $meta->args->{mapping}->[0]; > > # This limits to using a mapping table. Hard to imagine an = interface=20 > # for adding a has_many without a mapping table, but it could = be a table > # of just columns id, name, f_key, I suppose. > > die "Failed to find related_key for field [$field] in class = [$class]" unless $related_key; > > # Delete any items that are not to be kept > > for ( $foreign_class->search( { $foreign_key =3D> $item } ) ) { > $_->delete unless delete $keep{ $_->$related_key }; > } > > # Add in new ones > $foreign_class->create( { > $foreign_key =3D> $item, > $related_key =3D> $_, > } ) for keys %keep; ------_=_NextPart_001_01C5DACC.BE3F2593 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <HTML> <HEAD> <META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; = charset=3Diso-8859-1"> <META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version = 6.5.7232.39"> <TITLE>Re: [CDBI] delete from lookup table</TITLE> </HEAD> <BODY> <!-- Converted from text/rtf format --> <P><FONT SIZE=3D2 FACE=3D"Courier New">> Peter Speltz = [peterspeltz@xxxxx.xxx] wrote:</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">> What i have seen a = lot is is the use or "delete_all" on the results</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">> from a search.</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">> $class->search( id = =3D> $related_id)->delete_all;</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">> and if a = "my_method" is a has_many accessor i think you can say;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">> = $self->my_method(id =3D> $id)->delete_all;</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">Unfortunately this does not work = - it returns the mapped objects themselves. Thus, using</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">this code you end up deleting = both the entry in your lookup table *and* the the record for</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">the mapped object.</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">> I'm not sure if = has_many method will return an iterator in scalar</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">> context or = not.</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">In scalar context it is an = iterator, in list context a list of the proper objects.</FONT> </P> <BR> <P><FONT SIZE=3D2 FACE=3D"Courier New">> Bill Moseley = [moseley@xxxx.xxx] wrote:</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">> The use where I = needed something like this is when updating, say, a</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">> user form where = there's collection of checkboxes for "Roles" which are</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">> maintained in a = many_to_many table.</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">This is exactly my scenario - the = tables (simplified) are:</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New"> table USER with = columns 'id', 'name'</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New"> table = USER_GROUP_MAP with columns 'user_id', 'group_id'</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New"> table GROUP with = columns 'id', 'name'</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">The method containing the mapping = information is called 'mapped_groups'.</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">The code snippet Bill provided = (see below) does the right thing - and I did it more or less in the same = but a non-generic way by providing an extra sub in my USER class. The = thing I do not really like about Bill's code is the need to dig into the = object's hash structure - because there is no method available to = retrieve the necessary information. I'd rather have a somewhat 'cleaner' = way of deleting the mapping data.</FONT></P> <BR> <P><FONT SIZE=3D2 FACE=3D"Courier New">That said I think it'd be very = nice to have something like these 'add_to_XXX' (in this case: = 'add_to_mapped_groups') methods for removing the mapping information = like:</FONT></P> <P><FONT SIZE=3D2 FACE=3D"Courier New"> $user -> = delete_from_mapped_groups(@group_objects_to_be_deleted);</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">I believe that CDBI should have = all the necessary information internally to be able to dynamically = create something like this? Correct me if I am wrong (I have not had a = detailed look at the CDBI's internals).</FONT></P> <P><FONT SIZE=3D2 FACE=3D"Courier New">WDL</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">----------------</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">Bill's code:</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier New">>BTW -- I'm not that clear on = what the "mapping" array can hold -- seem</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">>like it's always a one = element array.</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Courier = New">> # here, $class is = "User" and $field->name is "roles"</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> $meta =3D = $class->meta_info('has_many')->{$field->name};</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> # Grab the value = from the form field</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> my $value =3D = $field->value;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> # Figure out which = values to keep:</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> my %keep =3D map { = $_ =3D> 1 } ref $value ? @$value : ( $value );</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> # Get foreign class = and its key that points to $class</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> my $foreign_class = =3D $meta->foreign_class; # Mapping class</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> my = $foreign_key =3D $meta->args->{foreign_key};</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> my = $related_key =3D = $meta->args->{mapping}->[0];</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> # This limits to = using a mapping table. Hard to imagine an interface </FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> # for adding a = has_many without a mapping table, but it could be a table</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> # of just columns = id, name, f_key, I suppose.</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> die "Failed to = find related_key for field [$field] in class [$class]" unless = $related_key;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> # Delete any items = that are not to be kept</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> for ( = $foreign_class->search( { $foreign_key =3D> $item } ) ) {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> &nbs= p; $_->delete unless delete $keep{ $_->$related_key };</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier New">></FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> # Add in new = ones</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> = $foreign_class->create( {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> &nbs= p; $foreign_key =3D> $item,</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> &nbs= p; $related_key =3D> $_,</FONT> <BR><FONT SIZE=3D2 FACE=3D"Courier = New">> } ) for keys = %keep;</FONT> </P> </BODY> </HTML> ------_=_NextPart_001_01C5DACC.BE3F2593-- --===============1154549139== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ ClassDBI mailing list ClassDBI@xxxxx.xxxxxxxxxxxxxxxx.xxx http://lists.digitalcraftsmen.net/mailman/listinfo/classdbi --===============1154549139==--
[CDBI] delete from lookup table
|
Re: [CDBI] delete from lookup table
|
Re: [CDBI] delete from lookup table
|
Re: [CDBI] delete from lookup table
|
Re: [CDBI] delete from lookup table
|
Re: [CDBI] delete from lookup table
|
Re: [CDBI] delete from lookup table
|
Generated at 14:18 on 27 Oct 2005 by mariachi v0.52