[Dbix-class] Unable to call result class method...
Amiri Barksdale
amiri at metalabel.com
Sun Mar 28 20:37:44 GMT 2010
I am having a weird problem, I think with relationships, but I don't
know what's wrong. I have two schema classes: the document belongs to
the template, and the template has many documents. The template has a
subroutine that is supposed to do some stuff for me in a controller
later. But I cannot call it as expected:
$document->template->document_class. I can call it if I find the
template first, e.g., $c->model('DB::Template')->find({ id => $id }),
and then do $template->document_class.
Here's the template class:
package W::S::R::Template;
...
__PACKAGE__->table("template");
__PACKAGE__->add_columns(
"id",
{ data_type => "integer",
default_value => \"nextval('template_id_seq')",
is_auto_increment => 1,
is_nullable => 0,
},
"name",
{ data_type => "text", default_value => undef, is_nullable => 0 },
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->has_many(
"documents",
"W::S::R::Document",
{ "foreign.template_id" => "self.id" },
{ cascade_delete => 1 },
);
...
sub document_class {
#print STDERR @_;
my ( $self, $template_id ) = @_;
switch ($template_id) {
case 1 {
return
$self->result_source->schema
->resultset('WillNoChildren')->find( { id => 1 } );
}
case 2 {
return
$self->result_source->schema
->resultset('StatutoryPowerAttorney')->find( { id => 1 } );
}
case 3 {
return
$self->result_source->schema
->resultset('StatutoryPowerAttorney')->find( { id => 1 } );
}
}
}
1;
Here's the document class:
package W::S::R::Document;
use Moose;
extends 'W::S::R';
use Warner::Types::Library qw/:all/;
use namespace::autoclean;
__PACKAGE__->table("document");
__PACKAGE__->add_columns(
...
"template_id",
{
data_type => "integer",
default_value => undef,
is_foreign_key => 1,
is_nullable => 0,
},
...
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to(
"template",
"W::S::R::Template",
{ "foreign.id" => "self.template_id" },
{ cascade_delete => 1 },
);
...
1;
In a controller:
sub index : Chained('base') : PathPart('') Args(0) {
my ( $self, $c ) = @_;
my $document = $c->session->{document};
my $template = $c->model('DB::Template')->find({ id =>
$document->template_id });
$c->log->debug(ref $template); ## OK
$c->log->debug($document->template_id); ## OK
$c->log->debug($document->template->document_class);
...
}
That last line throws the error:
Caught exception in Warner::Web::Controller::Checkout->index "Can't call
method "select_single" on an undefined value at
/home/amiri/warner/lib/perl5/DBIx/Class/ResultSet.pm line 750."
These tests all pass:
ok(my $document = $schema->resultset('Document')->new_result({
template_id => 1, user => 1 }), 'created new will_no_children document
OK');
is(ref $document->template, 'W::S::R::Template',
'documents template accessor delivers proper type');
is($document->template_id, '1', 'documents template id is correct');
is(ref $document->template->document_class($document->template_id),
'W::S::R::WillNoChildren', 'document_class sub returns
proper object');
I wrote another set of tests that finds a document and then calls
$document->template methods, and that works too.
Amiri
More information about the DBIx-Class
mailing list