[Dbix-class] Updating many-to-many relationships
David Cantrell
david at cantrell.org.uk
Tue Feb 21 16:11:56 GMT 2012
I have a bunch of classes set up as part of the ACL system for this 'ere
application what I'm writing. There is a 'user' table, a 'role' table,
and sitting in between them a 'user_role' table. Users can have any
arbitrary combination of roles, so this is yer classic many-to-many
situation. Pared down to the minimum, the classes are:
package Database::Result::User;
use base 'DBIx::Class::Core';
__PACKAGE__->table('user');
__PACKAGE__->add_columns(
id => { data_type => 'INT', is_nullable => 0 }, # autoinc
status => { data_type => 'CHAR', is_nullable => 0 },
username => { data_type => 'CHAR', is_nullable => 0 }
);
__PACKAGE__->set_primary_key( "id" );
__PACKAGE__->has_many( "user_roles", "Database::Result::UserRole", { 'foreign.user_id' => "self.id" } );
1;
package Database::Result::UserRole;
use base 'DBIx::Class::Core';
__PACKAGE__->table('user_role');
__PACKAGE__->add_columns(
user_id => { data_type => 'INT', is_nullable => 0 },
role_id => { data_type => 'INT', is_nullable => 0 },
);
__PACKAGE__->set_primary_key( qw(user_id role_id) );
__PACKAGE__->belongs_to("user", "Database::Result::User", { 'foreign.id' => 'self.user_id' });
__PACKAGE__->belongs_to("role", "Database::Result::Role", { 'foreign.id' => 'self.role_id' });
1;
package Database::Result::Role;
use base 'DBIx::Class::Core';
__PACKAGE__->table('role');
__PACKAGE__->add_columns(
id => { data_type => 'INT', is_nullable => 0 }, # autoinc
name => { data_type => 'CHAR', is_nullable => 0 },
);
__PACKAGE__->set_primary_key( "id" );
__PACKAGE__->has_many( "user_roles", "Database::Result::UserRole", { 'foreign.role_id' => "self.id" } );
1;
I can create users with roles easily, creating roles on the fly if
necessary:
my $person = ...->create({
username => 'anselm',
status => 'alive',
user_roles => [
{ role => { name => 'Monk' } },
{ role => { name => 'Archbishop' } },
]
});
I couldn't see this documented anywhere, but found it in the mailing
list archives. It creates any necessary entries in the 'role' table,
and in the 'user_role' table.
However, I can't find any nice way of updating a user's
roles, something like this (which I tried, but it doesn't work) ...
$person->status('dead');
$person->user_roles([
{ role => { name => 'Saint' } }
]);
$person->update();
Am I missing something? It would make my life ever so pleasant if there
were a nice easy way of doing this. As it is, however, the call to the
user_roles() method is not having any effect at all - there's no queries
generated whatsoever for it, just the UPDATE to change the status from
alive to dead.
--
David Cantrell | even more awesome than a panda-fur coat
There is no one true indentation style,
But if there were K&R would be Its Prophets.
Peace be upon Their Holy Beards.
More information about the DBIx-Class
mailing list