[Dbix-class] DBIC tests for where attribute in relations

Charlie Garrison garrison at zeta.org.au
Sun Sep 28 19:47:08 BST 2008


Good morning,

I've been working on DBIC::Tree::NestedSet::Multi which requires 
where attributes in the relationships. And I've been getting 
strange resultsets and after some discussion on irc I've had a 
go at writing a test. I'm still new at writing unit tests though 
so I may not have good test code.

I want to see SQL that looks like:

     SELECT me.tagid, me.cd, me.tag
     FROM cd cd, tags me ON ( tags.cd = me.cdid )
     WHERE ( me.cd = ? AND me.tag = ? ): '2', 'Cheesy'

But I'm getting this instead:

     SELECT me.tagid, me.cd, me.tag
     FROM tags me, cd cd
     WHERE ( ( ( me.cd = ? ) AND ( me.tag = ? ) ) ) : '2', 'Cheesy'

Excerpts from the code below:

# 66relationship_where.t
# this works as expected
$rs = $schema->resultset('CD')->search(
     {cd=>2, 'tags.tag'=>'Cheesy'}, {join => 'tags'});   # 
tagid=5, cdid=2
# this generates broken SQL
$rs = $schema->resultset('CD')->find(2)->cheesy_tags(); # 
tagid=5, cdid=2

# CD.pm
__PACKAGE__->has_many(
     cheesy_tags => 'DBICTest::Schema::Tag', undef,
     {
         where    => {"me.tag" => 'Cheesy'},
         from     =>  "tags me, cd cd",
     },
);

So it looks like the problem is with the join condition being 
dropped, or otherwise broken. During testing I have also seen 
the join (or where) condition change from something like:

     children.gid = me.gid

to:
     me.gid = 1

It was suggested by groditi that I should do some is_deeply 
checks on the relations, but I'm not sure how to achieve that.

So, suggestions for improving/extending the test would be 
appreciated. And if it's a DBIC bug then are any core devs able 
to have a look at it?


Thanks,
Charlie



Index: t/lib/DBICTest/Schema/CD.pm
===================================================================
--- t/lib/DBICTest/Schema/CD.pm (revision 4850)
+++ t/lib/DBICTest/Schema/CD.pm (working copy)
@@ -40,6 +40,20 @@
      { order_by => 'tag' },
  );
  __PACKAGE__->has_many(
+    cheesy_tags => 'DBICTest::Schema::Tag', undef,
+    {
+        where    => {"me.tag" => 'Cheesy'},
+        from     =>  "tags me, cd cd",
+    },
+);
+__PACKAGE__->has_many(
+    cheesy_tags_cond => 'DBICTest::Schema::Tag', {'foreign.cd' 
=> 'self.cdid'},
+    {
+        where    => {"me.tag" => 'Cheesy'},
+        from     =>  "tags me, cd cd",
+    },
+);
+__PACKAGE__->has_many(
      cd_to_producer => 'DBICTest::Schema::CD_to_Producer' => 'cd'
  );



t/66relationship_where.t
===================================================================
use strict;
use warnings;

use Test::More;
use lib qw(t/lib);
use DBICTest;

my $schema = DBICTest->init_schema();

plan tests => 1;

my $cheesy_cds1a = $schema->resultset('Tag')->search({cd=>2, 
'tag'=>'Cheesy'}); # tagid=5
# my $cheesy_cds1b = $schema->resultset('CD')->search({cd=>2, 
'tags.tag'=>'Cheesy'}, {join => 'tags'}); # tagid=5, cdid=2
my $cheesy_cds2a  = 
$schema->resultset('CD')->find(2)->cheesy_tags();   # tagid=5, cdid=2
# my $cheesy_cds2b  = 
$schema->resultset('CD')->find(2)->cheesy_tags_cond();    # 
tagid=5, cdid=2

is_deeply(
     [map { $_->id } $cheesy_cds1a->all],
     [map { $_->id } $cheesy_cds2a->all],
     'we got the same Tags',
)  or diag("Expected: \n",
             (map { $_->id."\n" } $cheesy_cds1a->all) ,
             "Got: \n",
             (map { $_->id."\n" } $cheesy_cds2a->all) ,
         );



-- 
    Charlie Garrison  <garrison at zeta.org.au>
    PO Box 141, Windsor, NSW 2756, Australia

O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
http://www.ietf.org/rfc/rfc1855.txt



More information about the DBIx-Class mailing list