[Dbix-class] Re: Template creates objects via belongs_to (how to lay out relationships)

Brian Kirkbride brian.kirkbride at deeperbydesign.com
Fri Jun 15 16:58:35 GMT 2007


Matt Rosin wrote:
> P.S. I should add that TT2 does not seem to let you test existence of a 
> related object, it just autovivifies. The .defined command and other 
> things I tried were not usable. However in my Perl code I am able to do 
> such tests (i.e. get_column, or check to see if customer is defined).
> 
>  
> 
> So I am not sure if the autovivification is only something from TT2 or 
> if it happens in the Perl code too (this is in a Catalyst environment 
> with MySQL). Thanks.
> 
>  
> 
> Matt

No, this is not limited to TT2, it is (I believe) the intended 
behaviour of a belongs_to relationship.  I can verify that something like:

My::Foo->belongs_to(bar => 'My::Bar', 'bar');

$foo = My::Foo->find(1);
$foo->update({bar => 1234}); # doesn't exist
unless ($foo->bar) {
	die("Not found");
}

will not die, but rather create a Bar row with pk 1234.  This appears 
to be by design, as belongs_to creates an accessor of type "filter" 
which will call find_or_create() instead of find() on the related 
table (Bar in this case).

I think this only happens when the rel accessor is shared with the 
column accessor for the join.  Meaning that a rel named "bar" on 
"bar_id" would not have this problem, because the accessor type would 
be "single" instead of "filter".

I can understand the thinking that $foo->bar() should not be set if 
the corresponding row doesn't exist, thus the autovivification.  In 
most cases this is something that would be enforced by constraints 
within the DB.

But in my case I'd much rather it return undef or even throw an 
exception upon not finding the related row.  An exception is probably 
much better than undef to differentiate from NULL.

Does this call for a new relationship type?  Or maybe a different 
accessor type?  I must admit that I do not fully grasp "single" vs 
"filter" accessors.

If it were a new relationship type, it could also default to a 
join_type of 'LEFT'.  Something like My::Foo->might_belong_to() maybe?

I'm sure the DBIC devs can shed some light on this discussion.  There 
might be some syntax I'm not aware of to force the behavior I'm 
looking for.

Best,
Brian Kirkbride



More information about the Dbix-class mailing list