Fix copy() assuming all columns are native
Peter Rabbitson [Mon, 15 Sep 2014 09:55:53 +0000 (11:55 +0200)]
Changes
lib/DBIx/Class/Row.pm
t/row/copy_with_extra_selection.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index 4a830a2..5639669 100644 (file)
--- a/Changes
+++ b/Changes
@@ -45,6 +45,7 @@ Revision history for DBIx::Class
         - Fix set_column on non-native (+columns) selections (RT#86685)
         - Fix set_inflated_column incorrectly handling \[] literals (GH#44)
         - Ensure that setting a column to a literal invariably marks it dirty
+        - Fix copy() not working correctly with extra selections present
         - Work around exception objects with broken string overloading in one
           additional codepath (missed in 0.08260)
         - Fix more inconsistencies of the quote_names attribute propagating
index f785773..630d2bc 100644 (file)
@@ -1147,14 +1147,14 @@ is set by default on C<has_many> relationships and unset on all others.
 sub copy {
   my ($self, $changes) = @_;
   $changes ||= {};
-  my $col_data = { %{$self->{_column_data}} };
+  my $col_data = { $self->get_columns };
 
   my $rsrc = $self->result_source;
 
-  my $colinfo = $rsrc->columns_info([ keys %$col_data ]);
+  my $colinfo = $rsrc->columns_info;
   foreach my $col (keys %$col_data) {
     delete $col_data->{$col}
-      if $colinfo->{$col}{is_auto_increment};
+      if ( ! $colinfo->{$col} or $colinfo->{$col}{is_auto_increment} );
   }
 
   my $new = { _column_data => $col_data };
diff --git a/t/row/copy_with_extra_selection.t b/t/row/copy_with_extra_selection.t
new file mode 100644 (file)
index 0000000..c1e3df4
--- /dev/null
@@ -0,0 +1,31 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+my $cd = $schema->resultset('CD')->search({}, {
+  '+columns' => { avg_year => $schema->resultset('CD')->get_column('year')->func_rs('avg')->as_query },
+  order_by => 'cdid',
+})->next;
+
+my $ccd = $cd->copy({ cdid => 5_000_000, artist => 2 });
+
+cmp_ok(
+  $ccd->id,
+  '!=',
+  $cd->id,
+  'IDs differ'
+);
+
+is(
+  $ccd->title,
+  $cd->title,
+  'Title same on copied object',
+);
+
+done_testing;