[Dbix-class] Re: many_to_many accessor returned object with undef
column
David Schmidt
davewood at gmx.at
Fri Jan 8 14:12:08 GMT 2010
On Fri, Jan 8, 2010 at 2:46 PM, David Schmidt <davewood at gmx.at> wrote:
> I add some roles, then add a user and give him some roles.
> if i want to print the roles using
>
> foreach ($user->roles) { print "Role: " . $_->name . ", " . $_->id . "\n"; }
>
> I get
>
> Role: admin, 1
> Role: undef, 2
> Role: undef, 3
>
> If I use $_->get_column('name') I get
> Role: admin, 1
> Role: user, 2
> Role: project, 3
>
> Dumping the code with
> die Dumper [$user->roles->search ({}, { result_class =>
> 'DBIx::Class::ResultClass::HashRefInflator'})->all ];
> returns
>
> $VAR1 = [
> {
> 'name' => 'admin',
> 'id' => '1'
> },
> {
> 'name' => 'user',
> 'id' => '2'
> },
> {
> 'name' => 'project',
> 'id' => '3'
> }
> ];
>
>
> My conclusion:
> the $user->roles accessor returns rows and only the row with id 1
> returns a value for the name column using $row->name. the other rows
> return the value only with $row->get_column('name'). im confused here
> :)
>
> I am a bit out of ideas here, all the details follow. I think its a
> bit fishy that for the admin (with id 1) a name is returned but not
> for the others.
>
>
>
> DBIC_TRACE output:
>
> SELECT me.id, me.name, me.email, me.password, me.created, me.updated,
> me.status FROM users me WHERE ( me.id = ? ): '1'
> SELECT role.id, role.name FROM user_roles me JOIN roles role ON
> role.id = me.role_id WHERE ( me.user_id = ? ): '1'
>
> #SELECT role.id, role.name FROM user_roles me JOIN roles role ON
> role.id = me.role_id WHERE ( me.user_id = 1);
> #+----+---------+
> #| id | name |
> #+----+---------+
> #| 1 | admin |
> #+----+---------+
> #| 2 | user |
> #+----+---------+
> #| 3 | project |
> #+----+---------+
>
> #########
> # USERS #
> #########
>
> __PACKAGE__->table("users");
> __PACKAGE__->add_columns(
> "id", { ... },
> "name", { ... },
> );
>
> __PACKAGE__->has_many(
> 'user_roles',
> 'MyApp::Schema::Result::UserRoles',
> 'user_id',
> { cascade_delete => 1 },
> );
>
> __PACKAGE__->many_to_many(
> 'roles',
> 'user_roles',
> 'role'
> );
>
>
> #########
> # ROLES #
> #########
>
> __PACKAGE__->table("roles");
> __PACKAGE__->add_columns(
> "id", { ... },
> "name", { ... },
> );
>
> __PACKAGE__->has_many(
> 'user_roles',
> 'MyApp::Schema::Result::UserRoles',
> 'role_id'
> );
>
> __PACKAGE__->many_to_many(
> 'users',
> 'user_roles',
> 'user'
> );
>
>
> #############
> # USERROLES #
> #############
>
> __PACKAGE__->table("user_roles");
> __PACKAGE__->add_columns(
> "user_id", { ... },
> "role_id", { ... },
> );
>
> __PACKAGE__->belongs_to(
> 'user',
> 'MyApp::Schema::Result::Users',
> 'user_id'
> );
>
> __PACKAGE__->belongs_to(
> 'role',
> 'MyApp::Schema::Result::Roles',
> 'role_id'
> );
>
>
> # DATA in DB
> select * from users;
> +----+-------+
> | id | name |
> +----+-------+
> | 1 | david |
> +----+-------+
>
> select * from roles;
> +----+---------+
> | id | name |
> +----+---------+
> | 1 | admin |
> | 3 | project |
> | 2 | user |
> +----+---------+
>
> select * from user_roles;
> +---------+---------+
> | user_id | role_id |
> +---------+---------+
> | 1 | 1 |
> +---------+---------+
> | 1 | 2 |
> +---------+---------+
> | 1 | 3 |
> +---------+---------+
>
Solved,
the mistake is in
"name",
{
data_type => "varchar",
is_nullable => 0,
is_enum => 1,
extra => { list => [qw/admin/] },
},
should be
extra => { list => [qw/admin user project/] },
thanks to everyone who helped in the IRC channel
david
More information about the DBIx-Class
mailing list