[Catalyst] YA CRUD module

David Schmidt davewood at gmx.at
Sun Dec 4 23:46:47 GMT 2011


just thought i'll keep you up to day so you dont waste time trying to
help with a problem i already solved.

Turns out the error cause was in one of the roles. It required a
method declared in the same role.

The CatalystX::SimpleLogin (using CatalystX::InjectComponent and
CatalystX::Component::Traits) way actually worked.
Now I have to figure out how to inject more then just one Controller.

good night

On 4 December 2011 17:24, David Schmidt <davewood at gmx.at> wrote:
> davewood: I have a problem with CatalystX::Component::Traits. When i
> apply 2 traits and one requires some methods provided by the other an
> error appears saying ... "Couldn't instantiate component ... requires
> the methods ..."
>
> Caelum: davewood: you can't do that, the traits are applied all at once
>
>
>
> Guess I'll try to inject a controller and add the traits then. like
> CatalystX::SimpleLogin does it.
>
>
>
>
> On 4 December 2011 14:37, David Schmidt <davewood at gmx.at> wrote:
>> Hi t0m
>>
>> I am currently stuck at configuring/applying roles via TestApp::config
>>
>> I want to apply the role via catalyst config in MyApp.pm
>>
>> __PACKAGE__->config(
>>   'Controller::Resource' => {
>>      resultset_key => 'cds_rs',
>>      resources_key => 'cds',
>>      resource_key => 'cd',
>>      model => 'DB::CDs',
>>      traits => ['
>>         '+CatalystX::Controller::TraitFor::Resource',
>>         '+CatalystX::Controller::TraitFor::Role::List',
>>      ],
>>   },
>> );
>>
>> Using 'CatalystX::Component::Traits'; I get a test to run when I only
>> apply the Resource trait. But once I add the List role the following
>> error appears.
>>
>> $ prove -l t/04_with_role.t
>> t/04_with_role.t .. Couldn't instantiate component
>> "TestApp::Controller::Root",
>> "'CatalystX::TraitFor::Controller::Resource|CatalystX::TraitFor::Controller::Role::List'
>> requires the methods 'resources_key' and 'resultset_key' to be
>> implemented by 'Moose::Meta::Class::__ANON__::SERIAL::11' at
>> /usr/local/lib/perl/5.10.1/Moose/Meta/Role/Application.pm line 53
>>        Moose::Meta::Role::Application::apply('Moose::Meta::Role::Application::ToClass=HASH(0xa3732a0)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::12=HASH(0xa3684e8)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa355838)') called at
>> /usr/local/lib/perl/5.10.1/Moose/Meta/Role/Application/ToClass.pm line
>> 33
>>        Moose::Meta::Role::Application::ToClass::apply('Moose::Meta::Role::Application::ToClass=HASH(0xa3732a0)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::12=HASH(0xa3684e8)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa355838)',
>> 'HASH(0xa3813e8)') called at
>> /usr/local/lib/perl/5.10.1/Moose/Meta/Role.pm line 482
>>        Moose::Meta::Role::apply('Moose::Meta::Class::__ANON__::SERIAL::12=HASH(0xa3684e8)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa355838)') called at
>> /usr/local/share/perl/5.10.1/MooseX/MethodAttributes/Role/Meta/Role/Application.pm
>> line 26
>>        Class::MOP::Class:::around('CODE(0x9966858)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::12=HASH(0xa3684e8)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa355838)') called at
>> /usr/local/lib/perl/5.10.1/Class/MOP/Method/Wrapped.pm line 161
>>        Class::MOP::Method::Wrapped::__ANON__('Moose::Meta::Class::__ANON__::SERIAL::12=HASH(0xa3684e8)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa355838)') called at
>> /usr/local/lib/perl/5.10.1/Class/MOP/Method/Wrapped.pm line 91
>>        Moose::Meta::Class::__ANON__::SERIAL::12::apply('Moose::Meta::Class::__ANON__::SERIAL::12=HASH(0xa3684e8)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa355838)') called at
>> /usr/local/lib/perl/5.10.1/Moose/Util.pm line 157
>>        Moose::Util::_apply_all_roles('Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa355838)',
>> undef, 'CatalystX::TraitFor::Controller::Resource',
>> 'CatalystX::TraitFor::Controller::Role::List') called at
>> /usr/local/lib/perl/5.10.1/Moose/Util.pm line 93
>>        Moose::Util::apply_all_roles('Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa355838)',
>> 'CatalystX::TraitFor::Controller::Resource',
>> 'CatalystX::TraitFor::Controller::Role::List') called at
>> /usr/local/lib/perl/5.10.1/Moose/Meta/Class.pm line 98
>>        Moose::Meta::Class::create('Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa2f59a0)',
>> 'Moose::Meta::Class::__ANON__::SERIAL::11', 'roles',
>> 'ARRAY(0xa33d798)', 'weaken', '', 'superclasses', 'ARRAY(0x9ba6ac8)')
>> called at /usr/local/lib/perl/5.10.1/Class/MOP/Package.pm line 121
>>        Class::MOP::Package::create_anon('Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa2f59a0)',
>> 'superclasses', 'ARRAY(0x9ba6ac8)', 'roles', 'ARRAY(0xa33d798)',
>> 'cache', 1) called at /usr/local/lib/perl/5.10.1/Class/MOP/Class.pm
>> line 473
>>        Class::MOP::Class::create_anon_class('Moose::Meta::Class::__ANON__::SERIAL::5=HASH(0xa2f59a0)',
>> 'superclasses', 'ARRAY(0x9ba6ac8)', 'roles', 'ARRAY(0xa33d798)',
>> 'cache', 1) called at
>> /usr/local/share/perl/5.10.1/MooseX/Traits/Pluggable.pm line 120
>>        MooseX::Traits::Pluggable::_build_instance_with_traits('TestApp::Controller::Root',
>> 'TestApp::Controller::Root', 'TestApp') called at
>> /usr/local/share/perl/5.10.1/MooseX/Traits/Pluggable.pm line 97
>>        MooseX::Traits::Pluggable::new_with_traits('TestApp::Controller::Root',
>> 'TestApp', 'HASH(0xa301858)') called at
>> /usr/local/share/perl/5.10.1/CatalystX/Component/Traits.pm line 145
>>        CatalystX::Component::Traits::COMPONENT('TestApp::Controller::Root',
>> 'TestApp', 'HASH(0xa1306b8)') called at
>> /usr/local/share/perl/5.10.1/Catalyst.pm line 2525
>>        eval {...} called at /usr/local/share/perl/5.10.1/Catalyst.pm line 2525
>>        Catalyst::setup_component('TestApp',
>> 'TestApp::Controller::Root') called at
>> /usr/local/share/perl/5.10.1/Catalyst.pm line 2452
>>        Catalyst::setup_components('TestApp') called at
>> /usr/local/share/perl/5.10.1/Catalyst.pm line 1179
>>        Catalyst::setup('TestApp') called at
>> /home/david/CatalystX-TraitFor-Controller-Resource/t/lib/TestApp.pm
>> line 24
>>        require TestApp.pm called at t/04_with_role.t line 9
>>        main::BEGIN() called at
>> /home/david/CatalystX-TraitFor-Controller-Resource/t/lib/TestApp.pm
>> line 0
>>        eval {...} called at
>> /home/david/CatalystX-TraitFor-Controller-Resource/t/lib/TestApp.pm
>> line 0"Compilation failed in require at t/04_with_role.t line 9.
>> BEGIN failed--compilation aborted at t/04_with_role.t line 9.
>> # Looks like your test exited with 9 before it could output anything.
>> t/04_with_role.t .. Dubious, test returned 9 (wstat 2304, 0x900)
>> Failed 3/3 subtests
>>
>> Test Summary Report
>> -------------------
>> t/04_with_role.t (Wstat: 2304 Tests: 0 Failed: 0)
>>  Non-zero exit status: 9
>>  Parse errors: Bad plan.  You planned 3 tests but ran 0.
>> Files=1, Tests=0,  1 wallclock secs ( 0.00 usr  0.06 sys +  0.37 cusr
>> 0.68 csys =  1.11 CPU)
>> Result: FAIL
>>
>>
>> # t/04_with_role.t
>>  1 use strict;
>>  2 use warnings;
>>  3
>>  4 use FindBin;
>>  5 use lib "$FindBin::Bin/lib";
>>  6
>>  7 use Test::More tests => 3;
>>  8
>>  9 use TestApp;
>>  10
>>  11 my $testapp = TestApp->new();
>>  12
>>  13 my $controller = $testapp->controller('Root');
>>  14 isa_ok ( $controller, 'TestApp::Controller::Root' );
>>  15
>>  16 my $action;
>>  17 $action = $controller->action_for('base');
>>  18 ok ( defined($action), 'Action "base" exists.' );
>>  19
>>  20 my $action = $controller->action_for('list');
>>  21 ok ( defined($action), 'Action "list" exists.' );
>>
>> # TestApp.pm
>>  1 package TestApp;
>>  2
>>  3 use strict;
>>  4 use warnings;
>>  5 use Catalyst;
>>  6
>>  7 use Moose;
>>  8 use namespace::autoclean;
>>  9
>>  10 __PACKAGE__->config(
>>  11     name => 'TestApp',
>>  12     'Controller::Root' => {
>>  13         resultset_key   => 'cds_rs',
>>  14         resources_key   => 'cds',
>>  15         resource_key    => 'cd',
>>  16         model           => 'DB::CDs',
>>  17         traits => [
>>  18             '+CatalystX::TraitFor::Controller::Resource,
>>  19             '+CatalystX::TraitFor::Controller::Role::List'',
>>  20         ],
>>  21     }
>>  22 );
>>  23
>>  24 __PACKAGE__->setup();
>>  25
>>  26 1;
>>
>>
>>  1 package TestApp::Controller::Root;
>>  2
>>  3 use Moose;
>>  4 BEGIN { extends 'Catalyst::Controller'; }
>>  5 with 'CatalystX::Component::Traits';
>>  6
>>  7 __PACKAGE__->config->{namespace} = '';
>>  8
>>  9 sub index : Path Args(0) {
>>  10     my ($self, $c) = @_;
>>  11     $c->res->body('index');
>>  12 }
>>  13
>>  14 1;
>>
>>
>> On 31 October 2011 22:08, Tomas Doran <bobtfish at bobtfish.net> wrote:
>>>
>>> On 31 Oct 2011, at 14:49, David Schmidt wrote:
>>>
>>>> It's about time I publish my first CPAN module and it happens to be
>>>> yet another CRUD module.
>>>>
>>>> Feedback greatly appreciated.
>>>
>>>
>>>
>>> I haven't looked at this in depth - but it generally looks nice (other than
>>> lack of tests).. But some comments:
>>>
>>> You don't need strict or warnings. MX::MethodAttributes::Role gives you all
>>> the same stuff Moose::Role does, which includes strict and warnings.
>>>
>>> It might be nice if you could split the roles up..
>>>
>>> So there would be a (very base) role, and then separate
>>> List/Show/Edit/Create/Delete roles, and the main role would just compose
>>> everything...
>>>
>>> But that would allow you to more easily / naturally only use a subset of the
>>> functionality, whilst implementing some of the code in a more custom manor..
>>> Of course you can do this by adding around method modifiers to methods -
>>> however having several classes with half a dozen modifiers each which
>>> redirect to a 404 (to remove edit / delete functionality) is a lot less nice
>>> than only composing a subset of the roles (if for no other reason than that
>>> the wrapped things will show up in the debug table)..
>>>
>>> The documentation on parent_key doesn't quite seem to make sense, and the
>>> predicate naming there is also not clear.. (It may make sense why it isn't
>>> called what you expect - but could do with a comment?)
>>>
>>> form_class could be made a MooseX::Types::LoadableClass to avoid the
>>> explicit class load.
>>>
>>> I intensely dislike your sub _redirect - couldn't you instead compute a
>>> private path, and pass that to $c->uri_for_action to produce a 'proper' URI?
>>>
>>> This would enable people to use your resources at sub-path parts, as you
>>> could pass the captures in.
>>>
>>> e.g.
>>>
>>> /user/<id>
>>> /user/<id>/.... resources from your role
>>> /user/<id>/document/<id>
>>> /user/<id>/document/<id>/.... resources from your role
>>>
>>> In the latter case, you could / would chain off the base_with_id action for
>>> the user id... This is the part where it becomes 'fun', and where your
>>> 'parent' functionality comes in - I guess these two things could be nicely
>>> combined... :)
>>>
>>> Is it sensible to give it an 'index' action? I'd be tempted to rename this
>>> to 'list', so that if someone wanted to override the default index, they
>>> could just override the PathPart of the 'list' action, and provide their own
>>> index action..
>>>
>>> Your delete works with GET requests. This is a horribly bad idea as it makes
>>> GETs stop being idempotent... Same deal with edit/create I guess...
>>>
>>> I look forward to seeing a TestApp - this code looks like a great start on
>>> something really interesting :)
>>>
>>> Cheers
>>> t0m
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> 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/



More information about the Catalyst mailing list