Mailing List Archive

automatically updating a join table
Hello

I am new to Perl and Catalyst, I hope I my terminology correct. much
gratitude to the authors of the fine Catalyst documentation, the
tutorials are excellent tools of understanding...

I have been through the tutorial and am currently modelling after the
authentication and authorization article on the advent calendar found
here:

http://www.catalystframework.org/calendar/2011/15

The goal:

I want users of roleB to create new users that are automatically set to
roleA. So I created an authentication chain, and have created a related
set of templates and forms to play with. The goal is to remove the Role
selection option and have the userroles join table updated automatically
at user creation time.

The efforts:

I started in Form/EditUser.pm has_field arguments by setting a "default
=> 1" argument and omitting the field from displaying in the template,
but it did not update the join field.

I found in HTML::FormHandler::Manual::Defaults an explanation that if
the item object contains an accessor, the default won't be used. since
in following the example I am using an accessor, it seems I will not
succeed using the form to set the value.

I looked at the useradd sub in the example again, I saw fields being
automatically set like so:

my $user = $c->model('DB::User')->new_result({});
$user->password($temp_password);

So I figured I should be able to use the accessor to do the same in the
join table, maybe like:

$user->userroles({'roleid' => '1'});

This, nor any variation on syntax I tried, does not update the join
table when the user is created.

I went back through the basicCRUD tutorial, and found the example where
the book_author table is updated, and it uses an argument called
create_related (or add_to_$rel), so I tried

$user->create_related('userroles', {roleid => '1'});

It actually works quite well in that when the form is processed the user
is created and the proper entries are made in the join table, but has
the unfortunate side effect of creating an empty user every time I hit
the form as well.

In digging around, I found also a new_related function, which based on
what I read should do exactly what create_related does, except only when
the form is processed and not when I touch the form:

$user->new_related('userroles', {roleid => '1'});

But this also does not update the join table when the user is created.

The question:

have I discovered the right tool but used it incorrectly, or am I going
about this the wrong way? If the former, that is all I need to know, I
will dance with what I have till the light comes on. If the latter, can
someone please point me at the page I need to read?

Thank you for taking the time to read...


--
Computerisms
Bob Miller
867-334-7117 / 867-633-3760
http://computerisms.ca




_______________________________________________
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/
Re: automatically updating a join table [ In reply to ]
Having in mind you are new to perl, do not continue development untill you
learn about Data::Dumper and Data::Printer. With these tools you can Dump
the contents of variables/objects and see which methods and attributes are
avaliable, and you can see the type of those variables/objects.

You can do so by trying:

$ perl -e 'use URI; my $x=URI->new("http://www.bla.com/bla") ; use DDP;
warn p $x; '\

So when you do that with $user, you will find out $user is actually related
to DBIx::Class object. And, that method create_related is actually related
to DBIx::Class.

When you do: $c->model('DB::User')->new_result({}); You are actually
using the DB::User model which is a DBIx::Class table class.

DBIx::Class is the orm the tutorial uses. And also probably the most
complete orm from all the existing programing languages.

If you want to learn more about DBIx::Class, you must read the
documentation:
http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/ResultSet.pm#new_result

I would suggest you halt your development there, and start another "quicky"
one that will only use DBIx::Class orm. So you can create 1 'test table' in
your sql test database with a couple rows. Then, you can make a quick
script (a simple perl.pl file) and try to create, update, delete and select
rows from that table using the DBIx::Class orm. Also have in mind that
people often call DBIx::Class as dbic. That simple perl script would look
something like this:

0. create a simple database with a simple table with a couple of columns.
(you can do that in your database)
1. create the orm schema using *DBIx*::*Class*::*Schema*::*Loader *like
this:

dbicdump -o dump_directory=./lib \
-o debug=1 \
DB::Some::Database::Namespace \
'dbi:Pg:dbname=your_database_name' \
myuser \
mypassword

2. create a script.pl that will use the generated schema:

use lib ( "./lib" );
use DBSchema; medico
my $schema = DBSchema->connect('dbi:Pg:dbname=your_database_name',
'hernan', 'lopes');
my $plant = $schema->resultset('Plant')->find({ id => 1});
#search in table Plant where id = 1
print $plant->color; #green

check the dsn correct for your database... dbi::Pg:dbname is for
postgres. Lookup the one you must use.

also, when you execute the script.pl you can do so with the
DBIC_TRACE=1 option, ie: $ export DBIC_TRACE=1 && perl script.pl

That way you will see debug output.

One handy dbic row method is:
http://search.cpan.org/~ribasushi/DBIx-Class-0.08250/lib/DBIx/Class/Row.pm#update_or_insert

try using that one. When you are able to insert, update and search and
find, try creating relationships among tables and re-run the dbicdump
command so your orm mappings get updated. Also, remember ->search
returns multiple items and ->find is for 1 item.

then you will be able to continue on that example you are working on,
all by yourself.



And, welcome to perl and catalyst, I hope you are being able to do
what you need. Its powerful tools once you master them.




On Thu, Jun 5, 2014 at 8:20 PM, Bob Miller <bob@computerisms.ca> wrote:

> Hello
>
> I am new to Perl and Catalyst, I hope I my terminology correct. much
> gratitude to the authors of the fine Catalyst documentation, the
> tutorials are excellent tools of understanding...
>
> I have been through the tutorial and am currently modelling after the
> authentication and authorization article on the advent calendar found
> here:
>
> http://www.catalystframework.org/calendar/2011/15
>
> The goal:
>
> I want users of roleB to create new users that are automatically set to
> roleA. So I created an authentication chain, and have created a related
> set of templates and forms to play with. The goal is to remove the Role
> selection option and have the userroles join table updated automatically
> at user creation time.
>
> The efforts:
>
> I started in Form/EditUser.pm has_field arguments by setting a "default
> => 1" argument and omitting the field from displaying in the template,
> but it did not update the join field.
>
> I found in HTML::FormHandler::Manual::Defaults an explanation that if
> the item object contains an accessor, the default won't be used. since
> in following the example I am using an accessor, it seems I will not
> succeed using the form to set the value.
>
> I looked at the useradd sub in the example again, I saw fields being
> automatically set like so:
>
> my $user = $c->model('DB::User')->new_result({});
> $user->password($temp_password);
>
> So I figured I should be able to use the accessor to do the same in the
> join table, maybe like:
>
> $user->userroles({'roleid' => '1'});
>
> This, nor any variation on syntax I tried, does not update the join
> table when the user is created.
>
> I went back through the basicCRUD tutorial, and found the example where
> the book_author table is updated, and it uses an argument called
> create_related (or add_to_$rel), so I tried
>
> $user->create_related('userroles', {roleid => '1'});
>
> It actually works quite well in that when the form is processed the user
> is created and the proper entries are made in the join table, but has
> the unfortunate side effect of creating an empty user every time I hit
> the form as well.
>
> In digging around, I found also a new_related function, which based on
> what I read should do exactly what create_related does, except only when
> the form is processed and not when I touch the form:
>
> $user->new_related('userroles', {roleid => '1'});
>
> But this also does not update the join table when the user is created.
>
> The question:
>
> have I discovered the right tool but used it incorrectly, or am I going
> about this the wrong way? If the former, that is all I need to know, I
> will dance with what I have till the light comes on. If the latter, can
> someone please point me at the page I need to read?
>
> Thank you for taking the time to read...
>
>
> --
> Computerisms
> Bob Miller
> 867-334-7117 / 867-633-3760
> http://computerisms.ca
>
>
>
>
> _______________________________________________
> 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/
>