See attached for an updated version of
t/relationship/update_or_create_single.t, which demonstrates the bug.
(Actually, attached both a patch against current version, and the
whole file, depending on which is easier for you to handle)

This test fails against .08124 of DBIC.

Toby

On 16 December 2010 13:53, Toby Corkindale <[email protected]> wrote:
> I think I have found a bug in find_or_create(), although maybe it's
> more a case of "it should throw an error if you try this", instead of
> silenting doing the Wrong Thing.
>
> Viz:
>
> Assume you have these tables:
> table1, with columns "luser" and "role".
> The primary key is on "luser, role".
> "role" is a foreign key into table2..
>
> table2 has columns "id" and "name".
>
> my $rs = $schema->resultset('table1');
> $rs->find_or_create(
>  {
>    luser => 'john',
>    role => { name => 'Admin' },
>  }
> );
>
> In this case, the SELECT that dbix class does to try and find the user
> will be WHERE luser='john' AND role=NULL.
>
> When it then creates the row, it will correctly fill it in with the ID
> from the role table.
> Eg. like:
> INSERT INTO mytable (luser,role)
> VALUES ('john', (SELECT id FROM role WHERE name='Admin'));
>
>
> Umm.. Would you like me to try and make a (failing) test case for dbic for 
> this?
> Or am I just being stupid.. It's more than possible :)
>
> Cheers,
> Toby

Attachment: update_or_create_single.t
Description: Troff document

From 7649e2e7726fe4a39aec9b2eb1883451c8e9a9ec Mon Sep 17 00:00:00 2001
From: Toby Corkindale <[email protected]>
Date: Mon, 20 Dec 2010 13:27:09 +1100
Subject: [PATCH] Add test for sub-levels in find_or_create.

Currently failing.
---
 t/relationship/update_or_create_single.t |   48 +++++++++++++++++++++++++++++-
 1 files changed, 47 insertions(+), 1 deletions(-)

diff --git a/t/relationship/update_or_create_single.t b/t/relationship/update_or_create_single.t
index a0e31fb..416a130 100644
--- a/t/relationship/update_or_create_single.t
+++ b/t/relationship/update_or_create_single.t
@@ -7,7 +7,7 @@ use DBICTest;
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 9;
+plan tests => 20;
 
 my $artist = $schema->resultset ('Artist')->first;
 
@@ -95,3 +95,49 @@ is_deeply (
   },
   'CD year column updated correctly without a disambiguator',
 );
+
+
+# Test multi-level find-or-create functionality.
+# We should be able to find-or-create this twice, with the second time
+# returning the same item and genre as the first..
+# This first test has the sub-level query on a non-unique key, ie. it
+# isn't checked as part of the "find" half of the method.
+
+my $genre_name = 'Highlander';
+my %cd_details = (
+    year => '2010',
+    title => 'Tasty Treats',
+    genre => { name => $genre_name }
+);
+my $genre2 = $schema->resultset ('Genre')
+            ->create ({ name => $genre_name });
+
+my $found1 = $artist->find_or_create_related('cds', { %cd_details });
+ok($found1->id, "Found (actually created) album in first iteration");
+is($found1->genre->name, $genre_name, ".. with correct genre");
+
+my $found2 = $artist->find_or_create_related('cds', { %cd_details });
+ok($found2->id, "Found album in second iteration");
+is($found2->id, $found1->id, "..and the IDs are the same.");
+is($found2->genre->name, $genre_name, ".. with correct genre");
+
+
+# Now we repeat the tests, using a sub-level query on one of the critical
+# keys that IS used in the "find" part.
+# Unfortunately DBIC's generated SQL looks for "artist=NULL" here.
+my $artist_name = 'Peanut and Cashew Mix';
+my %new_cd = (
+    year => '2011',
+    title => 'Various Failures',
+    artist => { name => $artist_name },
+);
+my $found3 = $genre2->find_or_create_related('cds', { %new_cd });
+ok($found3->id, "Found (actually created) album in first iteration");
+is($found3->artist->name, $artist_name, "..with correct artist name");
+
+my $found4 = $genre2->find_or_create_related('cds', { %new_cd });
+ok($found4->id, "Found album in second iteration");
+is($found4->id, $found3->id, "..and the IDs are the same.");
+is($found4->artist->name, $artist_name, ".. with correct artist name");
+is($found4->artist->id, $found3->artist->id, "..matching artist ids");
+
-- 
1.7.3.4

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/[email protected]

Reply via email to