Instead of role.role_id.role you should do role.role.role obviously that's silly in how confusing it is, so eventually if I were you i'd make the column in the role table to be called name, and then instead of calling user_roles role, call then user_role. That would make the above user_role.role.name.
Sorry, for the top post, replying from my phone On Jul 11, 2012 10:58 AM, "Robyn Jonahs" <learn.catal...@gmail.com> wrote: > Hi, > > I am working through the chapter in the book to learn about many to many > relationship bridges. > > I have made it through the chapter up to the last part where it has us > list all users and their roles. Page 165 in Chapter 6. > > This is the template file root/authusers/list.tt > > <html> > <head> > <title>All users and their roles</title> > </head> > <body> > > <table> > <tr><th>UserID</th><th> > Username</th><th>eMail</th><th>Roles</th></tr> > [% WHILE (user = users_rs.next) %] > <tr> > <td>[% user.id %]</td> > <td>[% user.username %]</td> > <td>[% user.email %]</td> > <td> > <ul> > [% FOREACH role = user.user_roles %] > <li>[% role.role_id.role %]</li> > [% END %] > </ul> > </td> > </tr> > [% END %] > </table> > > </body> > </html> > > > If I remove the last "role" in the FOREACH loop it will list the id for > the roles. It fails to list the text associated with the roles and I can't > figure out what is going wrong. The only major difference between the book > and what has happened for me locally is that DBIx::Class::Schema::Loader > (version 0.07025 ) created the schema results as > > DBAuthTest$ ls lib/Auth/Schema/Result/ > Role.pm User.pm UserRole.pm > > Not the plurals as in the book (Roles.pm, User.pm and UserRoles.pm). I > have been trying to track these names and keep it consistent with what I am > doing as opposed to the book instructions and so far I have worked through > it. > > The result gives the <li> dots but no values. So it is counting them > correctly but not retrieving the values. I am stumped on this and any help > at all would be greatly appreciated. > > > > > > > > The other relevant files are: > ======== The Controller ========= > > lib/DBAuthTest/Controller/AuthUsers.pm > > > > package DBAuthTest::Controller::AuthUsers; > use Moose; > use namespace::autoclean; > > BEGIN {extends 'Catalyst::Controller'; } > > =head1 NAME > > DBAuthTest::Controller::AuthUsers - Catalyst Controller > > =head1 DESCRIPTION > > Catalyst Controller. > > =head1 METHODS > > =cut > > > =head2 index > > =cut > > sub base : Chained('/'): PathPart('authusers'): CaptureArgs(0) { > my ( $self, $c ) = @_; > > $c->stash(users_rs => $c->model('AuthDB::User')); > $c->stash(roles_rs => $c->model('AuthDB::Role')); > } > > > sub add : Chained('base'): PathPart('add'): Args(0) { > my ( $self, $c ) = @_; > > if(lc $c->req->method eq 'post') { > my $params = $c->req->params; > > ## Retrieve the users_rs stashed by the base action: > my $users_rs = $c->stash->{users_rs}; > > ## Create the user: > =head2 Original Code > - keep for now as I don't trust the code below. > > my $newuser = $users_rs->create({ > username => $params->{username}, > email => $params->{email}, > password => $params->{password}, > }); > =cut > =head2 Catching Errors > - No Workiee, not in their code either. > =cut > my $newuser = eval { $users_rs->create({ > username => $params->{username}, > email => $params->{email}, > password => $params->{password}, > }) }; > if($@) { > $c->log->debug( > "User tried to sign up with an invalid email address, redoing..."); > $c->stash( errors => { email => 'invalid' }, err => $@ ); > return; > } > > return $c->res->redirect( $c->uri_for( > $c->controller('AuthUsers')->action_for('profile'), > [ $newuser->id ] > ) ); > > } > > } > > > sub user : Chained('base'): PathPart(''): CaptureArgs(1) { > my ($self, $c, $userid) = @_; > > my $user = $c->stash->{users_rs}->find({ id => $userid },{ key => > 'primary' }); > > die "No such user" if(!$user); > > $c->stash(user => $user); > } > > > sub profile : Chained('user') :PathPart('profile'): Args(0) { > my ($self, $c) = @_; > > } > > > sub edit : Chained('user') :PathPart('edit'): Args(0) { > my ($self, $c) = @_; > > if(lc $c->req->method eq 'post') { > my $params = $c->req->params; > my $user = $c->stash->{user}; > > ## Check user is allowed to update this profile > #if($c->user->object->id != $user->id) { > # die "Malicious attempt to update another user by: ". > $c->user->username; > #} > > ## Update user's email and/or password > $user->update({ > email => $params->{email}, > password => $params->{password}, > }); > > ## Send the user back to the changed profile > return $c->res->redirect( $c->uri_for( > $c->controller('AuthUsers')->action_for('profile'), [ $user->id ] ) > ); > } > } > > > =head2 Original > sub set_roles :Chained('user'): PathPart('set_roles'): Args() { > my ($self, $c) = @_; > > my $user = $c->stash->{user}; > if(lc $c->req->method eq 'post') { > > ## Fetch all role ids submitted as a list > my @roles = $c->req->param('role'); > > ## Remove any existing roles, we're replacing them: > $user->user_roles->delete; > > ## Add new roles: > foreach my $role_id (@roles) { > $user->user_roles->create({ role_id => $role_id }); > } > } > > $c->res->redirect($c->uri_for($c->controller()->action_for('profile'),[ > $user->id ] )); > } > =cut > sub set_roles :Chained('user'): PathPart('set_roles'): Args() { > my ($self, $c) = @_; > > my $user = $c->stash->{user}; > if(lc $c->req->method eq 'post') { > > ## Fetch all role ids submitted as a list > my @roles = $c->req->param('role'); > > $user->set_all_roles(@roles); > } > > $c->res->redirect($c->uri_for($c->controller()->action_for('profile'), > [ $user->id ] )); > } > > > sub delete :Chained('user'): PatPart('delete'): Args() { > my ($self, $c) = @_; > my $user = $c->stash->{user}; > $user->delete(); > > return $c->res->redirect( $c->uri_for('/') ); > } > > > sub list : Chained('base'): PathPart('list'): Args(0) { > my ($self, $c) = @_; > } > > __PACKAGE__->meta->make_immutable; > > 1; > > > ------- The Result Classes ------ > DBAuthTest$ ls lib/Auth/Schema/Result/ > Role.pm User.pm UserRole.pm > > > ======== User.pm ============= > use utf8; > package Auth::Schema::Result::User; > > # Created by DBIx::Class::Schema::Loader > # DO NOT MODIFY THE FIRST PART OF THIS FILE > > =head1 NAME > > Auth::Schema::Result::User > > =cut > > use strict; > use warnings; > > use Moose; > use MooseX::NonMoose; > use MooseX::MarkAsMethods autoclean => 1; > extends 'DBIx::Class::Core'; > > =head1 COMPONENTS LOADED > > =over 4 > > =item * L<DBIx::Class::InflateColumn::DateTime> > > =item * L<DBIx::Class::TimeStamp> > > =back > > =cut > > __PACKAGE__->load_components("InflateColumn::DateTime", "TimeStamp"); > > =head1 TABLE: C<users> > > =cut > > __PACKAGE__->table("users"); > > =head1 ACCESSORS > > =head2 id > > data_type: 'integer' > is_auto_increment: 1 > is_nullable: 0 > > =head2 username > > data_type: 'text' > is_nullable: 1 > > =head2 email > > data_type: 'text' > is_nullable: 1 > > =head2 password > > data_type: 'text' > is_nullable: 1 > > =head2 last_modified > > data_type: 'datetime' > is_nullable: 1 > > =cut > > __PACKAGE__->add_columns( > "id", > { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, > "username", > { data_type => "text", is_nullable => 1 }, > "email", > { data_type => "text", is_nullable => 1 }, > "password", > { data_type => "text", is_nullable => 1 }, > "last_modified", > { data_type => "datetime", is_nullable => 1 }, > ); > > =head1 PRIMARY KEY > > =over 4 > > =item * L</id> > > =back > > =cut > > __PACKAGE__->set_primary_key("id"); > > =head1 UNIQUE CONSTRAINTS > > =head2 C<username_unique> > > =over 4 > > =item * L</username> > > =back > > =cut > > __PACKAGE__->add_unique_constraint("username_unique", ["username"]); > > =head1 RELATIONS > > =head2 user_roles > > Type: has_many > > Related object: L<Auth::Schema::Result::UserRole> > > =cut > > __PACKAGE__->has_many( > "user_roles", > "Auth::Schema::Result::UserRole", > { "foreign.user_id" => "self.id" }, > { cascade_copy => 0, cascade_delete => 0 }, > ); > > =head2 roles > > Type: many_to_many > > Composing rels: L</user_roles> -> role > > =cut > > __PACKAGE__->many_to_many("roles", "user_roles", "role"); > > > # Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-09 00:18:52 > # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:6svl+CkzndehZ8+Zp5yXhw > > > # You can replace this text with custom code or comments, and it will be > preserved on regeneration > __PACKAGE__->meta->make_immutable; > > __PACKAGE__->add_columns('last_modified', > { %{__PACKAGE__->column_info('last_modified') }, > set_on_create => 1, > set_on_update => 1 > }); > > > use Email::Valid; > sub new { > my ($class, $args)=@_; > > if( exists $args->{email} && !Email::Valid->address($args->{email}) ) { > die 'Email invalid'; > } > > return $class->next::method($args); > } > > > sub has_role { > my ($self, $role) = @_; > > ## $role is a row object for a role > > my $roles = $self->user_roles->find({ role_id => $role->id }); > return $roles; > > } > > > sub set_all_roles { > my ($self, @roleids) = @_; > > ## Remove any existing roles, we're replacing them: > $self->user_roles->delete; > > ## Add new roles: > foreach my $role_id (@roleids) { > $self->user_roles->create({ role_id => $role_id }); > } > > return $self; > } > > > 1; > > > > ======== UserRole.pm ============= > > > use utf8; > package Auth::Schema::Result::UserRole; > > # Created by DBIx::Class::Schema::Loader > # DO NOT MODIFY THE FIRST PART OF THIS FILE > > =head1 NAME > > Auth::Schema::Result::UserRole > > =cut > > use strict; > use warnings; > > use Moose; > use MooseX::NonMoose; > use MooseX::MarkAsMethods autoclean => 1; > extends 'DBIx::Class::Core'; > > =head1 COMPONENTS LOADED > > =over 4 > > =item * L<DBIx::Class::InflateColumn::DateTime> > > =item * L<DBIx::Class::TimeStamp> > > =back > > =cut > > __PACKAGE__->load_components("InflateColumn::DateTime", "TimeStamp"); > > =head1 TABLE: C<user_roles> > > =cut > > __PACKAGE__->table("user_roles"); > > =head1 ACCESSORS > > =head2 user_id > > data_type: 'integer' > is_foreign_key: 1 > is_nullable: 0 > > =head2 role_id > > data_type: 'integer' > is_foreign_key: 1 > is_nullable: 0 > > =cut > > __PACKAGE__->add_columns( > "user_id", > { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, > "role_id", > { data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, > ); > > =head1 PRIMARY KEY > > =over 4 > > =item * L</user_id> > > =item * L</role_id> > > =back > > =cut > > __PACKAGE__->set_primary_key("user_id", "role_id"); > > =head1 RELATIONS > > =head2 role > > Type: belongs_to > > Related object: L<Auth::Schema::Result::Role> > > =cut > > __PACKAGE__->belongs_to( > "role", > "Auth::Schema::Result::Role", > { id => "role_id" }, > { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" }, > ); > > =head2 user > > Type: belongs_to > > Related object: L<Auth::Schema::Result::User> > > =cut > > __PACKAGE__->belongs_to( > "user", > "Auth::Schema::Result::User", > { id => "user_id" }, > { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" }, > ); > > > # Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-09 00:18:52 > # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:0RYpPqJtXPb7IMPYjImDng > > > # You can replace this text with custom code or comments, and it will be > preserved on regeneration > __PACKAGE__->meta->make_immutable; > 1; > > > > ======== Role.pm ============= > > use utf8; > package Auth::Schema::Result::Role; > > # Created by DBIx::Class::Schema::Loader > # DO NOT MODIFY THE FIRST PART OF THIS FILE > > =head1 NAME > > Auth::Schema::Result::Role > > =cut > > use strict; > use warnings; > > use Moose; > use MooseX::NonMoose; > use MooseX::MarkAsMethods autoclean => 1; > extends 'DBIx::Class::Core'; > > =head1 COMPONENTS LOADED > > =over 4 > > =item * L<DBIx::Class::InflateColumn::DateTime> > > =item * L<DBIx::Class::TimeStamp> > > =back > > =cut > > __PACKAGE__->load_components("InflateColumn::DateTime", "TimeStamp"); > > =head1 TABLE: C<roles> > > =cut > > __PACKAGE__->table("roles"); > > =head1 ACCESSORS > > =head2 id > > data_type: 'integer' > is_auto_increment: 1 > is_nullable: 0 > > =head2 role > > data_type: 'text' > is_nullable: 1 > > =cut > > __PACKAGE__->add_columns( > "id", > { data_type => "integer", is_auto_increment => 1, is_nullable => 0 }, > "role", > { data_type => "text", is_nullable => 1 }, > ); > > =head1 PRIMARY KEY > > =over 4 > > =item * L</id> > > =back > > =cut > > __PACKAGE__->set_primary_key("id"); > > =head1 UNIQUE CONSTRAINTS > > =head2 C<role_unique> > > =over 4 > > =item * L</role> > > =back > > =cut > > __PACKAGE__->add_unique_constraint("role_unique", ["role"]); > > =head1 RELATIONS > > =head2 user_roles > > Type: has_many > > Related object: L<Auth::Schema::Result::UserRole> > > =cut > > __PACKAGE__->has_many( > "user_roles", > "Auth::Schema::Result::UserRole", > { "foreign.role_id" => "self.id" }, > { cascade_copy => 0, cascade_delete => 0 }, > ); > > =head2 users > > Type: many_to_many > > Composing rels: L</user_roles> -> user > > =cut > > __PACKAGE__->many_to_many("users", "user_roles", "user"); > > > # Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-09 00:18:52 > # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:a8Hd9uGBQmPWRsNQd8WR6Q > > > # You can replace this text with custom code or comments, and it will be > preserved on regeneration > __PACKAGE__->meta->make_immutable; > 1; > > _______________________________________________ > List: Catalyst@lists.scsys.co.uk > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst > Searchable archive: > http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ > Dev site: http://dev.catalyst.perl.org/ > >
_______________________________________________ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/