Thanks, that worked. Now I am off to see why.
On Wed, Jul 11, 2012 at 12:26 PM, fREW Schmidt <fri...@gmail.com> wrote: > 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/ > >
_______________________________________________ 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/