[Catalyst] The Definitive Guide to Catalyst ... p. 165 listing all users and their roles

Robyn Jonahs learn.catalyst at gmail.com
Wed Jul 11 16:29:39 GMT 2012


Thanks, that worked. Now I am off to see why.



On Wed, Jul 11, 2012 at 12:26 PM, fREW Schmidt <frioux at 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 abo=
ve
> user_role.role.name.
>
> Sorry, for the top post, replying from my phone
> On Jul 11, 2012 10:58 AM, "Robyn Jonahs" <learn.catalyst at 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 =3D users_rs.next) %]
>>     <tr>
>>       <td>[% user.id %]</td>
>>       <td>[% user.username %]</td>
>>       <td>[% user.email %]</td>
>>       <td>
>>         <ul>
>>           [% FOREACH role =3D 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 bo=
ok
>> 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 throu=
gh
>> 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 he=
lp
>> at all would be greatly appreciated.
>>
>>
>>
>>
>>
>>
>>
>> The other relevant files are:
>> =3D=3D=3D=3D=3D=3D=3D=3D The Controller =3D=3D=3D=3D=3D=3D=3D=3D=3D
>>
>> lib/DBAuthTest/Controller/AuthUsers.pm
>>
>>
>>
>> package DBAuthTest::Controller::AuthUsers;
>> use Moose;
>> use namespace::autoclean;
>>
>> BEGIN {extends 'Catalyst::Controller'; }
>>
>> =3Dhead1 NAME
>>
>> DBAuthTest::Controller::AuthUsers - Catalyst Controller
>>
>> =3Dhead1 DESCRIPTION
>>
>> Catalyst Controller.
>>
>> =3Dhead1 METHODS
>>
>> =3Dcut
>>
>>
>> =3Dhead2 index
>>
>> =3Dcut
>>
>> sub base : Chained('/'): PathPart('authusers'): CaptureArgs(0) {
>>     my ( $self, $c ) =3D @_;
>>
>>     $c->stash(users_rs =3D> $c->model('AuthDB::User'));
>>     $c->stash(roles_rs =3D> $c->model('AuthDB::Role'));
>> }
>>
>>
>> sub add : Chained('base'): PathPart('add'): Args(0) {
>>   my ( $self, $c ) =3D @_;
>>
>>   if(lc $c->req->method eq 'post') {
>>     my $params =3D $c->req->params;
>>
>>     ## Retrieve the users_rs stashed by the base action:
>>     my $users_rs =3D $c->stash->{users_rs};
>>
>>     ## Create the user:
>> =3Dhead2 Original Code
>>   - keep for now as I don't trust the code below.
>>
>>     my $newuser =3D $users_rs->create({
>>         username =3D> $params->{username},
>>         email    =3D> $params->{email},
>>         password =3D> $params->{password},
>>     });
>> =3Dcut
>> =3Dhead2 Catching Errors
>>   - No Workiee, not in their code either.
>> =3Dcut
>>     my $newuser =3D eval { $users_rs->create({
>>       username =3D> $params->{username},
>>       email    =3D> $params->{email},
>>       password =3D> $params->{password},
>>     }) };
>>     if($@) {
>>       $c->log->debug(
>>         "User tried to sign up with an invalid email address,
>> redoing...");
>>       $c->stash( errors =3D> { email =3D> 'invalid' }, err =3D> $@ );
>>       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) =3D @_;
>>
>>   my $user =3D $c->stash->{users_rs}->find({ id =3D> $userid },{ key =3D>
>> 'primary' });
>>
>>   die "No such user" if(!$user);
>>
>>   $c->stash(user =3D> $user);
>> }
>>
>>
>> sub profile : Chained('user') :PathPart('profile'): Args(0) {
>>   my ($self, $c) =3D @_;
>>
>> }
>>
>>
>> sub edit : Chained('user') :PathPart('edit'): Args(0) {
>>   my ($self, $c) =3D @_;
>>
>>   if(lc $c->req->method eq 'post') {
>>     my $params =3D $c->req->params;
>>     my $user    =3D $c->stash->{user};
>>
>>     ## Check user is allowed to update this profile
>>     #if($c->user->object->id !=3D $user->id) {
>>     #  die "Malicious attempt to update another user by: ".
>> $c->user->username;
>>     #}
>>
>>     ## Update user's email and/or password
>>     $user->update({
>>       email =3D> $params->{email},
>>       password =3D> $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 ] )
>> );
>>   }
>> }
>>
>>
>> =3Dhead2 Original
>> sub set_roles :Chained('user'): PathPart('set_roles'): Args() {
>>   my ($self, $c) =3D @_;
>>
>>   my $user =3D $c->stash->{user};
>>   if(lc $c->req->method eq 'post') {
>>
>>     ## Fetch all role ids submitted as a list
>>     my @roles =3D $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 =3D> $role_id });
>>     }
>>   }
>>
>>   $c->res->redirect($c->uri_for($c->controller()->action_for('profile'),[
>> $user->id ] ));
>> }
>> =3Dcut
>> sub set_roles :Chained('user'): PathPart('set_roles'): Args() {
>>   my ($self, $c) =3D @_;
>>
>>   my $user =3D $c->stash->{user};
>>   if(lc $c->req->method eq 'post') {
>>
>>     ## Fetch all role ids submitted as a list
>>     my @roles =3D $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) =3D @_;
>>   my $user =3D $c->stash->{user};
>>   $user->delete();
>>
>>   return $c->res->redirect( $c->uri_for('/') );
>> }
>>
>>
>> sub list : Chained('base'): PathPart('list'): Args(0) {
>>   my ($self, $c) =3D @_;
>> }
>>
>> __PACKAGE__->meta->make_immutable;
>>
>> 1;
>>
>>
>> ------- The Result Classes ------
>> DBAuthTest$ ls lib/Auth/Schema/Result/
>> Role.pm      User.pm      UserRole.pm
>>
>>
>> =3D=3D=3D=3D=3D=3D=3D=3D User.pm =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>> use utf8;
>> package Auth::Schema::Result::User;
>>
>> # Created by DBIx::Class::Schema::Loader
>> # DO NOT MODIFY THE FIRST PART OF THIS FILE
>>
>> =3Dhead1 NAME
>>
>> Auth::Schema::Result::User
>>
>> =3Dcut
>>
>> use strict;
>> use warnings;
>>
>> use Moose;
>> use MooseX::NonMoose;
>> use MooseX::MarkAsMethods autoclean =3D> 1;
>> extends 'DBIx::Class::Core';
>>
>> =3Dhead1 COMPONENTS LOADED
>>
>> =3Dover 4
>>
>> =3Ditem * L<DBIx::Class::InflateColumn::DateTime>
>>
>> =3Ditem * L<DBIx::Class::TimeStamp>
>>
>> =3Dback
>>
>> =3Dcut
>>
>> __PACKAGE__->load_components("InflateColumn::DateTime", "TimeStamp");
>>
>> =3Dhead1 TABLE: C<users>
>>
>> =3Dcut
>>
>> __PACKAGE__->table("users");
>>
>> =3Dhead1 ACCESSORS
>>
>> =3Dhead2 id
>>
>>   data_type: 'integer'
>>   is_auto_increment: 1
>>   is_nullable: 0
>>
>> =3Dhead2 username
>>
>>   data_type: 'text'
>>   is_nullable: 1
>>
>> =3Dhead2 email
>>
>>   data_type: 'text'
>>   is_nullable: 1
>>
>> =3Dhead2 password
>>
>>   data_type: 'text'
>>   is_nullable: 1
>>
>> =3Dhead2 last_modified
>>
>>   data_type: 'datetime'
>>   is_nullable: 1
>>
>> =3Dcut
>>
>> __PACKAGE__->add_columns(
>>   "id",
>>   { data_type =3D> "integer", is_auto_increment =3D> 1, is_nullable =3D>=
 0 },
>>   "username",
>>   { data_type =3D> "text", is_nullable =3D> 1 },
>>   "email",
>>   { data_type =3D> "text", is_nullable =3D> 1 },
>>   "password",
>>   { data_type =3D> "text", is_nullable =3D> 1 },
>>   "last_modified",
>>   { data_type =3D> "datetime", is_nullable =3D> 1 },
>> );
>>
>> =3Dhead1 PRIMARY KEY
>>
>> =3Dover 4
>>
>> =3Ditem * L</id>
>>
>> =3Dback
>>
>> =3Dcut
>>
>> __PACKAGE__->set_primary_key("id");
>>
>> =3Dhead1 UNIQUE CONSTRAINTS
>>
>> =3Dhead2 C<username_unique>
>>
>> =3Dover 4
>>
>> =3Ditem * L</username>
>>
>> =3Dback
>>
>> =3Dcut
>>
>> __PACKAGE__->add_unique_constraint("username_unique", ["username"]);
>>
>> =3Dhead1 RELATIONS
>>
>> =3Dhead2 user_roles
>>
>> Type: has_many
>>
>> Related object: L<Auth::Schema::Result::UserRole>
>>
>> =3Dcut
>>
>> __PACKAGE__->has_many(
>>   "user_roles",
>>   "Auth::Schema::Result::UserRole",
>>   { "foreign.user_id" =3D> "self.id" },
>>   { cascade_copy =3D> 0, cascade_delete =3D> 0 },
>> );
>>
>> =3Dhead2 roles
>>
>> Type: many_to_many
>>
>> Composing rels: L</user_roles> -> role
>>
>> =3Dcut
>>
>> __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 =3D> 1,
>>   set_on_update =3D> 1
>> });
>>
>>
>> use Email::Valid;
>> sub new {
>>   my ($class, $args)=3D at _;
>>
>>   if( exists $args->{email} && !Email::Valid->address($args->{email}) ) {
>>     die 'Email invalid';
>>   }
>>
>>   return $class->next::method($args);
>> }
>>
>>
>> sub has_role {
>>   my ($self, $role) =3D @_;
>>
>>   ## $role is a row object for a role
>>
>>   my $roles =3D $self->user_roles->find({ role_id =3D> $role->id });
>>   return $roles;
>>
>> }
>>
>>
>> sub set_all_roles {
>>   my ($self, @roleids) =3D @_;
>>
>>   ## 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 =3D> $role_id });
>>   }
>>
>>   return $self;
>> }
>>
>>
>> 1;
>>
>>
>>
>> =3D=3D=3D=3D=3D=3D=3D=3D UserRole.pm =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
>>
>>
>> use utf8;
>> package Auth::Schema::Result::UserRole;
>>
>> # Created by DBIx::Class::Schema::Loader
>> # DO NOT MODIFY THE FIRST PART OF THIS FILE
>>
>> =3Dhead1 NAME
>>
>> Auth::Schema::Result::UserRole
>>
>> =3Dcut
>>
>> use strict;
>> use warnings;
>>
>> use Moose;
>> use MooseX::NonMoose;
>> use MooseX::MarkAsMethods autoclean =3D> 1;
>> extends 'DBIx::Class::Core';
>>
>> =3Dhead1 COMPONENTS LOADED
>>
>> =3Dover 4
>>
>> =3Ditem * L<DBIx::Class::InflateColumn::DateTime>
>>
>> =3Ditem * L<DBIx::Class::TimeStamp>
>>
>> =3Dback
>>
>> =3Dcut
>>
>> __PACKAGE__->load_components("InflateColumn::DateTime", "TimeStamp");
>>
>> =3Dhead1 TABLE: C<user_roles>
>>
>> =3Dcut
>>
>> __PACKAGE__->table("user_roles");
>>
>> =3Dhead1 ACCESSORS
>>
>> =3Dhead2 user_id
>>
>>   data_type: 'integer'
>>   is_foreign_key: 1
>>   is_nullable: 0
>>
>> =3Dhead2 role_id
>>
>>   data_type: 'integer'
>>   is_foreign_key: 1
>>   is_nullable: 0
>>
>> =3Dcut
>>
>> __PACKAGE__->add_columns(
>>   "user_id",
>>   { data_type =3D> "integer", is_foreign_key =3D> 1, is_nullable =3D> 0 =
},
>>   "role_id",
>>   { data_type =3D> "integer", is_foreign_key =3D> 1, is_nullable =3D> 0 =
},
>> );
>>
>> =3Dhead1 PRIMARY KEY
>>
>> =3Dover 4
>>
>> =3Ditem * L</user_id>
>>
>> =3Ditem * L</role_id>
>>
>> =3Dback
>>
>> =3Dcut
>>
>> __PACKAGE__->set_primary_key("user_id", "role_id");
>>
>> =3Dhead1 RELATIONS
>>
>> =3Dhead2 role
>>
>> Type: belongs_to
>>
>> Related object: L<Auth::Schema::Result::Role>
>>
>> =3Dcut
>>
>> __PACKAGE__->belongs_to(
>>   "role",
>>   "Auth::Schema::Result::Role",
>>   { id =3D> "role_id" },
>>   { is_deferrable =3D> 1, on_delete =3D> "CASCADE", on_update =3D> "CASC=
ADE" },
>> );
>>
>> =3Dhead2 user
>>
>> Type: belongs_to
>>
>> Related object: L<Auth::Schema::Result::User>
>>
>> =3Dcut
>>
>> __PACKAGE__->belongs_to(
>>   "user",
>>   "Auth::Schema::Result::User",
>>   { id =3D> "user_id" },
>>   { is_deferrable =3D> 1, on_delete =3D> "CASCADE", on_update =3D> "CASC=
ADE" },
>> );
>>
>>
>> # 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;
>>
>>
>>
>> =3D=3D=3D=3D=3D=3D=3D=3D Role.pm =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>>
>> use utf8;
>> package Auth::Schema::Result::Role;
>>
>> # Created by DBIx::Class::Schema::Loader
>> # DO NOT MODIFY THE FIRST PART OF THIS FILE
>>
>> =3Dhead1 NAME
>>
>> Auth::Schema::Result::Role
>>
>> =3Dcut
>>
>> use strict;
>> use warnings;
>>
>> use Moose;
>> use MooseX::NonMoose;
>> use MooseX::MarkAsMethods autoclean =3D> 1;
>> extends 'DBIx::Class::Core';
>>
>> =3Dhead1 COMPONENTS LOADED
>>
>> =3Dover 4
>>
>> =3Ditem * L<DBIx::Class::InflateColumn::DateTime>
>>
>> =3Ditem * L<DBIx::Class::TimeStamp>
>>
>> =3Dback
>>
>> =3Dcut
>>
>> __PACKAGE__->load_components("InflateColumn::DateTime", "TimeStamp");
>>
>> =3Dhead1 TABLE: C<roles>
>>
>> =3Dcut
>>
>> __PACKAGE__->table("roles");
>>
>> =3Dhead1 ACCESSORS
>>
>> =3Dhead2 id
>>
>>   data_type: 'integer'
>>   is_auto_increment: 1
>>   is_nullable: 0
>>
>> =3Dhead2 role
>>
>>   data_type: 'text'
>>   is_nullable: 1
>>
>> =3Dcut
>>
>> __PACKAGE__->add_columns(
>>   "id",
>>   { data_type =3D> "integer", is_auto_increment =3D> 1, is_nullable =3D>=
 0 },
>>   "role",
>>   { data_type =3D> "text", is_nullable =3D> 1 },
>> );
>>
>> =3Dhead1 PRIMARY KEY
>>
>> =3Dover 4
>>
>> =3Ditem * L</id>
>>
>> =3Dback
>>
>> =3Dcut
>>
>> __PACKAGE__->set_primary_key("id");
>>
>> =3Dhead1 UNIQUE CONSTRAINTS
>>
>> =3Dhead2 C<role_unique>
>>
>> =3Dover 4
>>
>> =3Ditem * L</role>
>>
>> =3Dback
>>
>> =3Dcut
>>
>> __PACKAGE__->add_unique_constraint("role_unique", ["role"]);
>>
>> =3Dhead1 RELATIONS
>>
>> =3Dhead2 user_roles
>>
>> Type: has_many
>>
>> Related object: L<Auth::Schema::Result::UserRole>
>>
>> =3Dcut
>>
>> __PACKAGE__->has_many(
>>   "user_roles",
>>   "Auth::Schema::Result::UserRole",
>>   { "foreign.role_id" =3D> "self.id" },
>>   { cascade_copy =3D> 0, cascade_delete =3D> 0 },
>> );
>>
>> =3Dhead2 users
>>
>> Type: many_to_many
>>
>> Composing rels: L</user_roles> -> user
>>
>> =3Dcut
>>
>> __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 at 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 at 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/
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20120711/5070c=
981/attachment.htm


More information about the Catalyst mailing list