[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