[Dbix-class] Bug with relationships on new objects.
brett gardner
brett at clientcomm.com.au
Fri Jan 25 01:41:55 GMT 2008
Matt S Trout wrote:
> Which is, as I said, nothing to do with new vs. inflate_result.
>
> If you pass 'col =3D> undef' to new(), you get the fk =3D NULL.
>
> If you use the 'columns' resultset attr to restrict the col set to not
> include the column, you get the 'column does not exist'[0] behaviour.
>
> But all this is academic; if !has_column_loaded we should just be throwing
> an exception, not creating the resultset anyway.
>
> Who fancies having a go at a patch? :)
>
> [0] which you call 'column is not set', which is almost accurate but not
> quite :)
>
> =
Right, well I wrote a patch (attached) that fixes the problem, but then =
running the test harness showed a problem as it breaks the behaviour.
my $artist =3D $schema->resultset('Artist')->create({
name=3D>'foo',
cds=3D>[
{title=3D>'foo',year=3D>2000},
{title=3D>'bar',year=3D>2000},
]
);
The "new" method in "Row.pm" creates a new "Artist" and calls =
"new_related" for each of the "cds". Then when "insert" is called on the =
"Artist", it updates the related objects' "artistid" column and calls =
"insert" on each related object.
So the patch breaks this behaviour.
Brett
-------------- next part --------------
Index: 0.09/trunk/t/66relationship.t
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- 0.09/trunk/t/66relationship.t (revision 3972)
+++ 0.09/trunk/t/66relationship.t (working copy)
@@ -7,7 +7,7 @@
=
my $schema =3D DBICTest->init_schema();
=
-plan tests =3D> 62;
+plan tests =3D> 63;
=
# has_a test
my $cd =3D $schema->resultset("CD")->find(4);
@@ -211,6 +211,10 @@
is($def_artist_cd->has_column_loaded('artist'), 1, 'FK loaded');
is($def_artist_cd->search_related('artist')->count, 0, 'closed search on n=
ull FK');
=
+my $undef_artist =3D $schema->resultset('Artist')->new_result({name=3D>'fo=
o'});
+eval{$undef_artist->search_related('cds')};
+ok($@,'search_related where relationship requires primary key to be set th=
rows exception');
+
# test undirected many-to-many relationship (e.g. "related artists")
my $undir_maps =3D $schema->resultset("Artist")->find(1)->artist_undirecte=
d_maps;
is($undir_maps->count, 1, 'found 1 undirected map for artist 1');
Index: 0.09/trunk/lib/DBIx/Class/ResultSource.pm
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- 0.09/trunk/lib/DBIx/Class/ResultSource.pm (revision 3972)
+++ 0.09/trunk/lib/DBIx/Class/ResultSource.pm (working copy)
@@ -778,7 +778,7 @@
=
sub resolve_condition {
my ($self, $cond, $as, $for) =3D @_;
- #warn %$cond;
+
if (ref $cond eq 'HASH') {
my %ret;
foreach my $k (keys %{$cond}) {
@@ -789,8 +789,16 @@
$v =3D~ s/^self\.// ||
$self->throw_exception("Invalid rel cond val ${v}");
if (ref $for) { # Object
+ my $loaded =3D $for->has_column_loaded($v);
+ if (! $loaded){
+ for ($for->result_source->primary_columns){
+ if ($v eq $_){
+ $self->throw_exception('Calling a relationship on a ro=
w with no primary key');
+ }
+ }
+ }
#warn "$self $k $for $v";
- $ret{$k} =3D $for->get_column($v) if $for->has_column_loaded($v);
+ $ret{$k} =3D $for->get_column($v) if $loaded;
#warn %ret;
} elsif (!defined $for) { # undef, i.e. "no object"
$ret{$k} =3D undef;
More information about the DBIx-Class
mailing list