[Dbix-class] Re: Relations and inflation

Matt S Trout dbix-class at trout.me.uk
Sun Jun 24 15:24:41 GMT 2007


On Sun, Jun 24, 2007 at 06:27:29AM -0700, Matt Rosin wrote:
> Hello,
> 
> Thanks for your reply, Matt. I've boiled down code from my Catalyst project as follows.
> A bit disconcerting that the problem remains even though I've refactored it into a command line program. 

Not really, the root of the problem is in the database design, see below.

> In CatMgrDB::Listing below, I have added a number from 1 to 4 after the comment, so that 4 different relationships can be tried.
> 
> When the relation in Listing.pm is "belongs_to" (i.e. case 4) inflation works and the output is:
> # ./reltest.pl
> Name: Telebody Inc.
> Offer: Free website estimate
> 
> However when it is changed to "might_have" (case 1) the output is:
> # ./reltest.pl
> Name: Telebody Inc.
> Coupon is undefined
> 
> It also fails for case 2 (has_one) but (why??) it works for case 3 (wierd misuse of has_one, I think).

No, actually, case 3 is the closest you've come so far to something sane :)

> Listings follow.
> 
> Any light you can shed on this would be greatly appreciated. 
> 
> Meanwhile I have discovered something interesting, if I delete a coupon without zeroing the listing.coupon field, a new coupon with the same id is autovivified but with zeroes in all other fields. Which makes it impossible to delete with the existing code that looks at coupon.listing ...
>
> I really would like a way to disable autovivification. I don't believe it is "doing the right thing" if it keeps surprising me. Well I suppose I should be using might_have (if inflation would work with it) or allow nulls in the table.

It keeps surprising you because the defaults work for a normalised schema.

Yours isn't.

> root at host1 [/app/reltest]# cat CatMgrDB/Listing.pm
> package CatMgrDB::Listing;
> use base qw/DBIx::Class/;
> __PACKAGE__->load_components(qw/PK::Auto Core/);
> __PACKAGE__->table('listing');
> __PACKAGE__->add_columns(qw/id category customer banner whitepages type flagged disabled name address address2 city state zip phone offertext site directions locations menu template usermemo adminmemo codememo package coupon modified/);

Drop the coupon field, it's duplicate information.

> __PACKAGE__->set_primary_key('id');
> #__PACKAGE__->might_have(coupon => CatMgrDB::Coupon); #1 inflation fails with this

This is right, and will work perfectly once you've made the other changes
outlined below.

> 1;
> root at host1 [/app/reltest]# cat CatMgrDB/Coupon.pm
> package CatMgrDB::Coupon;
> use base qw/DBIx::Class/;
> __PACKAGE__->load_components(qw/PK::Auto Core/);
> __PACKAGE__->table('coupon');
> __PACKAGE__->add_columns(qw/id listing available flagged offer terms usermemo/); # and other columns

Drop the id field, it's unecessary since you only have at most one coupon per
listing.

> __PACKAGE__->set_primary_key('id');

Set listing as the primary key (and consider renaming to listing_id and
altering the third arg to the belongs_to rel appropriately).

> __PACKAGE__->belongs_to( listing  => 'CatMgrDB::Listing', 'listing', {join_type => 'left'});
> 1;

Drop the join_type, it's wrong unless you can have coupons without a listing,
which from what you've said so far you can't.

And with the above done, your might_have and belongs_to relations will work
fine, there'll be no unexpected autovivification -and- your database will
be in something approaching normal form.

Plus, you'll be able to set up a foreign key to match the belongs_to from
listing to coupon so your database is enforcing relational integrity - your
current design with circular relationships strongly suggests to me you
don't have foreign keys at all, which is a little on the dangerous side.

-- 
      Matt S Trout       Need help with your Catalyst or DBIx::Class project?
   Technical Director    Want a managed development or deployment platform?
 Shadowcat Systems Ltd.  Contact mst (at) shadowcatsystems.co.uk for a quote
http://chainsawblues.vox.com/             http://www.shadowcatsystems.co.uk/ 



More information about the Dbix-class mailing list