[Catalyst] Perplexed Catalyst newbie
John Romkey
romkey at apocalypse.org
Sun Apr 19 19:41:11 GMT 2009
On Apr 19, 2009, at 3:22 PM, Sean McAfee wrote:
> I'm trying to put together my first simple Catalyst application, a
> foreign language word quiz, and I'm a bit lost.
>
> In a simple program that uses DBIx::Class only, I might write:
>
> my @langs = $schema->resultset('Language')->all;
>
> I get a list of objects back of class Quiz::Schema::Language, as
> expected.
>
> In a handler in my Catalyst application, I'm writing:
>
> my @langs = $c->model('Language')->all;
>
> What I get back is a list of objects of class
> Quiz::Model::DB::Language. This leaves me scratching my head, since
> $c->model('Language') gives a DBIx::Class::ResultSet object, yet
> it's returning objects that are associated with my Catalyst class
> hierarchy. I had understood DBIx::Class to be an orthogonal
> component of my Catalyst app, but they seem to be intergrated here
> somehow.
>
> As far as I can recall, nowhere in the various Catalyst tutorials I
> worked through was it ever mentioned that ORM objects returned by my
> model would be wrapped by, or coerced into, or whatever, subpackages
> of my model class. Whatever Quiz::Model::DB::Language is, it's not
> a transparent wrapper, because when I call the count() method on one
> such object of which I know there should be three, I get undef (or
> possibly an empty string) back.
>
> Even stranger, when I walk my objects' has_many accessors, I
> sometimes get objects that are in a subpackage of my model class, as
> described above, but I also sometimes get unblessed array
> references. For example, in my current schema each language
> has_many sources, and each source has_many termsets. I have two
> languages in my database now, each with one source, each with one
> termset.
>
> [% FOR l IN lang; FOR s IN l.sources; s.termsets; END; END %]
>
> This TT snippet prints
>
> Quiz::Model::DB::Termset=HASH(0xcaa4d8)
> ARRAY(0xca4fb4)
>
> So now I'm completely confused. Any help would be massively
> appreciated.
This bit me a number of times when I was starting out with Catalyst.
When you call $schema->resultset('Language') you're passing in to
DBIx::Class::Schema the name of a ResultSet ('Language')
When you call $c->model('Language') you're passing in to Catalyst the
name of a Catalyst component which is a model. When the model
corresponds to a DBIx::Class::Schema object it's a wrapper which
passes stuff through.
If Catalyst doesn't find a direct match for the name, it does a
regular expression search across components to find one which matches.
This often gives you unexpected results (to put it mildly). Recent
revisions of Catalyst have issued loud warnings when it falls back to
the regex search.
To avoid the search, you'll have to qualify the model name. The last
time I wrote about this I screwed up the way that should be done, so
I'll try to do it better here. If the full name of your model is
Quiz::Model::DB::Language then you should pass DB::Language to $c-
>model(). That should avoid the regex search and get you back the
resultset that you're looking for rather than the Catalyst model
object that you're not.
- john romkey
http://www.romkey.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20090419/0127a4d7/attachment.htm
More information about the Catalyst
mailing list