[Catalyst] Perplexed Catalyst newbie

Sean McAfee eefacm at gmail.com
Mon Apr 20 04:51:42 GMT 2009


On Sun, Apr 19, 2009 at 2:49 PM, J. Shirley <jshirley at gmail.com> wrote:

> Catalyst::Model::DBIC::Schema simply looks at all available result sets a=
nd
> creates a model class that is a transparent wrapper.  It should function =
the
> exact same.
>
> The code that does this is:
>
>     foreach my $moniker ($self->schema->sources) {
>         my $classname =3D "${class}::$moniker";
>         *{"${classname}::ACCEPT_CONTEXT"} =3D sub {
>             shift;
>             shift->model($model_name)->resultset($moniker);
>
>         }
>
>     }
>
> As you can see, all it is doing is a short-hand to
> $c->model('DB')->resultset($moniker) ($moniker being the name, 'Language',
> $class being 'Quiz::Model::DB')
>
> That's how it works, but without seeing actual code in your application I=
'm
> not sure why you are getting unexpected results.
>

Okay, I've reduced my app to its most basic components, and renamed its
elements for simplicity.  A is the highest-level component; it has_many B's;
each B has_many C's.  Here are the source files, using what is hopefully an
intuitively obvious shell-like expansion notation for brevity:

File Quiz/Schema/{A,B,C}.pm:

package Quiz::Schema::{A,B.C};
use base 'DBIx::Class';
__PACKAGE__->load_components('Core');
__PACKAGE__->table('{A,B,C}');
__PACKAGE__->add_columns('{a,b,c}', {,'a','b'});
__PACKAGE__->set_primary_key('{a,b,c}');
1;

Quiz/Schema/A.pm and Quiz/Schema/B.pm each have one extra configuration
statement:

__PACKAGE__->has_many({bs,cs} =3D> 'Quiz::Schema::{B,C});

In my database, table A has a single column "a" and two rows with values 1
and 2.  Table B has columns "b" and "a" and two rows: b=3D1, a=3D1 and b=3D=
2,
a=3D2.   And table C has columns "c" and "b" and three rows: c=3D1, b=3D1; =
c=3D2,
b=3D2; and c=3D3, b=3D2.

To sum up: There are two A's, each of which has one B.  Of the two B's, one
has one C, and the other has two C's.

In my controller module, I have this routine:

sub index :Path :Args(0) {
  my ($self, $c) =3D @_;
  $c->stash->{as} =3D [ $c->model('DB::A')->all ];
  $c->stash->{template} =3D 'index.tt';
}

This is the content of my index.tt file:

[% FOR a IN as; FOR b IN a.bs; b.cs; "<br>"; END; END %]

And this is the output in my browser:

Quiz::Model::DB::C=3DHASH(0xc75e78)
ARRAY(0xc0c96c)

Now the corresponding plain DBIx::Class app, as I understand it, would be
similar to this:

for my $a ($schema->resultset('A')->all) {
  for my $b ($a->bs) {
    my $cs =3D $b->cs;
    print ref $cs, "\n";
  }
}

When I run this program, the output is:

DBIx::Class::ResultSet
DBIx::Class::ResultSet

I get a ResultSet back when I ask for any B's list of C's.  But when I go
through Catalyst, I (apparently) get an unblessed array reference back if
the B in question has more than one C.  So sometimes I get a genuine object
back, other times I get plain old data.  How am I supposed to code around
that?

Or probably the more correct question:  Where do my expectations diverge
from Catalyst's reality?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20090419/25903=
b8a/attachment.htm


More information about the Catalyst mailing list