Hi,

Many people seem to get caught by trying to call $row->some_relation
where the some_relation uses a column that does not exist in $row
(i.e. is not loaded - this can happen with new row or a when you don't
select all columns when creating the row).  This now returns some
strange results.

At irc mst asked me to make this an exception - so that it will be
more visible what went wrong.  In the attachments you'll find my patch
- there is still one test failing in t/96multi_create.t - I hope
someone will find out what's happening there and fix it.  This patch
does not fix anything for me personally, but rather breaks some of my
code and I did it only per mst request - so please don't blame me for
it.

Cheers,
Zbigniew Lukasiak
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/
Index: t/66relationship.t
===================================================================
--- t/66relationship.t	(revision 4489)
+++ t/66relationship.t	(working copy)
@@ -212,7 +212,10 @@
 
 my $undef_artist_cd = $schema->resultset("CD")->new_result({ 'title' => 'badgers', 'year' => 2007 });
 is($undef_artist_cd->has_column_loaded('artist'), '', 'FK not loaded');
-is($undef_artist_cd->search_related('artist')->count, 3, 'open search on undef FK');
+eval {
+    $undef_artist_cd->search_related('artist')->count
+};
+like($@, qr/Accessing not loaded column/, 'open search on undef FK');
 
 my $def_artist_cd = $schema->resultset("CD")->new_result({ 'title' => 'badgers', 'year' => 2007, artist => undef });
 is($def_artist_cd->has_column_loaded('artist'), 1, 'FK loaded');
Index: lib/DBIx/Class/Row.pm
===================================================================
--- lib/DBIx/Class/Row.pm	(revision 4489)
+++ lib/DBIx/Class/Row.pm	(working copy)
@@ -79,7 +79,12 @@
         {
           my $rel_obj = delete $attrs->{$key};
           if(!Scalar::Util::blessed($rel_obj)) {
-            $rel_obj = $new->find_or_new_related($key, $rel_obj);
+            if ( $new->has_column_loaded($key) ){
+              $rel_obj = $new->find_or_new_related($key, $rel_obj);
+            }
+            else {
+              $rel_obj = $new->result_source->related_source($key)->resultset->find_or_new($rel_obj);
+            }
           }
 
           $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
@@ -93,7 +98,12 @@
           my $others = delete $attrs->{$key};
           foreach my $rel_obj (@$others) {
             if(!Scalar::Util::blessed($rel_obj)) {
-              $rel_obj = $new->new_related($key, $rel_obj);
+              if ( $new->has_column_loaded($key) ){
+                $rel_obj = $new->new_related($key, $rel_obj);
+              }
+              else {
+                $rel_obj = $new->result_source->related_source($key)->resultset->new($rel_obj);
+              }
               $new->{_rel_in_storage} = 0;
             }
 
@@ -107,7 +117,12 @@
           ## 'filter' should disappear and get merged in with 'single' above!
           my $rel_obj = delete $attrs->{$key};
           if(!Scalar::Util::blessed($rel_obj)) {
-            $rel_obj = $new->find_or_new_related($key, $rel_obj);
+            if ( $new->has_column_loaded($key) ){
+              $rel_obj = $new->find_or_new_related($key, $rel_obj);
+            }
+            else {
+              $rel_obj = $new->result_source->related_source($key)->resultset->find_or_new($rel_obj);
+            }
             $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
           }
           $inflated->{$key} = $rel_obj;
Index: lib/DBIx/Class/ResultSource.pm
===================================================================
--- lib/DBIx/Class/ResultSource.pm	(revision 4489)
+++ lib/DBIx/Class/ResultSource.pm	(working copy)
@@ -796,7 +796,9 @@
         $self->throw_exception("Invalid rel cond val ${v}");
       if (ref $for) { # Object
         #warn "$self $k $for $v";
-        $ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
+        #confess "Accessing not loaded column $v for resolving relationship" if ! $for->has_column_loaded($v);
+        $self->throw_exception("Accessing not loaded column $v for resolving relationship") if ! $for->has_column_loaded($v);
+        $ret{$k} = $for->get_column($v);
         #warn %ret;
       } elsif (!defined $for) { # undef, i.e. "no object"
         $ret{$k} = undef;
_______________________________________________
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