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/
_______________________________________________
List: [email protected]
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/[email protected]/
Dev site: http://dev.catalyst.perl.org/