[Dbix-class] Easy update for has_many?

Jason Kohles email at jasonkohles.com
Wed Aug 22 15:29:53 GMT 2007


On Aug 22, 2007, at 7:50 AM, Paul Makepeace wrote:

> I have a standard has_many linking multiple groups profiles to a
> particular user,
>
>   My::Schema::User->has_many(user_profile => 'My:Schema::UserProfile',
> 	{ 'foreign.user_uid' => 'self.uid', } );
>
> UserProfile is the link class ("join") table: user_uid, profile_uid
>
> I'd like to be able to set a bunch of profile_uids and have the ORM
> sort out which need deletion and creation. Is this possible?
>
> I looked in the cookbook and there's examples on building the
> relationships ({has,many_to}_many) but not much (anything?) on using
> them.
>
There is probably a cleaner way, but this is how I'm doing it at the  
moment...

sub update_profiles {
	my ( $self, @profiles ) = @_;

	# make a hash mapping the profile_id to the object for all
	# the profiles the user currently has
	my %tmp = map { ( $_->profile_id => $_ ) } $self->profiles;

	# loop over all the profile ids they should have, as provided
	# in the arguments
	for my $pid ( @profiles ) {
		# if they should have it, and they do have it, then remove
		# the object from the temporary hash
		if ( exists $tmp{ $pid } ) {
			# undef rather than delete, in case you pass a
			# duplicate id in the arguments
			undef $tmp{ $pid };
		} else {
			# If they should have it, but don't, then add it
			$self->add_to_profiles( { profile_id => $pid } );
		}
	}

	# now go through the values of %tmp, anything that is
	# still an object, is a profile associated with them that
	# was not passed as an argument, and should be removed
	for my $old ( grep { defined } values %tmp ) {
		$old->delete;
	}
}

-- 
Jason Kohles
email at jasonkohles.com
http://www.jasonkohles.com/
"A witty saying proves nothing."  -- Voltaire





More information about the DBIx-Class mailing list