From c4f3c7567035eb4e7fb8acb575402f631a8d9f7d Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Mon, 8 Aug 2016 14:13:40 +0100 Subject: [PATCH] Bug 17080: Handle default values for NOT NULL columns from Koha::Object->new MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recently we face the same issue on different modules after we moved them to the Koha namespace using Koha::Object of using DBIx::Class directly. 1/ Koha::Patron::Modification on bug 16960 comment 14 and 15 2/ Koha::Patron::Category from bug 17069 3/ C4::Members::AddMember (which does not use Koha::Object) on bug 16917 If a DB column is defined as NOT NULL and has a default value, the DBIx::Class $rs->update_or_insert method won't use the default value if the column name has been passed to the constructor. We do that almost everywhere as we retrieve the data from the HTML forms without checking/cleaning them. There are several ways to fix that: 1/ Continue to fix them case by case (what we did for the recent issues) 2/ Try to fix them globally (existing ones and the next ones) This patch propose a global solution to avoid future issues of this kind. The idea is not to pass the undefined values which cannot be nullable to the DBIx::Class constructor. Tested all patches together. Works as expected. Signed-off-by: Marc VĂ©ron --- Koha/Object.pm | 13 +++++++++++-- t/db_dependent/Koha/Objects.t | 15 ++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Koha/Object.pm b/Koha/Object.pm index 9d23fb4..50c82a1 100644 --- a/Koha/Object.pm +++ b/Koha/Object.pm @@ -56,8 +56,17 @@ sub new { my $self = {}; if ($attributes) { - $self->{_result} = - Koha::Database->new()->schema()->resultset( $class->_type() ) + my $schema = Koha::Database->new->schema; + + # Remove the arguments which exist, are not defined but NOT NULL to use the default value + my $columns_info = $schema->resultset( $class->_type )->result_source->columns_info; + for my $column_name ( keys %$attributes ) { + my $c_info = $columns_info->{$column_name}; + next if $c_info->{is_nullable}; + next if not exists $attributes->{$column_name} or defined $attributes->{$column_name}; + delete $attributes->{$column_name}; + } + $self->{_result} = $schema->resultset( $class->_type() ) ->new($attributes); } diff --git a/t/db_dependent/Koha/Objects.t b/t/db_dependent/Koha/Objects.t index b92239a..00e6b9c 100644 --- a/t/db_dependent/Koha/Objects.t +++ b/t/db_dependent/Koha/Objects.t @@ -19,9 +19,11 @@ use Modern::Perl; -use Test::More tests => 2; +use Test::More tests => 3; use Koha::Authority::Types; +use Koha::Patron::Category; +use Koha::Patron::Categories; use Koha::Patrons; use Koha::Database; @@ -36,5 +38,16 @@ my @columns = Koha::Patrons->columns; my $borrowernumber_exists = grep { /^borrowernumber$/ } @columns; is( $borrowernumber_exists, 1, 'Koha::Objects->columns should return the table columns' ); +subtest 'new' => sub { + plan tests => 2; + my $a_cat_code = 'A_CAT_CODE'; + my $patron_category = Koha::Patron::Category->new( { categorycode => $a_cat_code } )->store; + is( Koha::Patron::Categories->find($a_cat_code)->category_type, 'A', 'Koha::Object->new should set the default value' ); + Koha::Patron::Categories->find($a_cat_code)->delete; + $patron_category = Koha::Patron::Category->new( { categorycode => $a_cat_code, category_type => undef } )->store; + is( Koha::Patron::Categories->find($a_cat_code)->category_type, 'A', 'Koha::Object->new should set the default value even if the argument exists but is not defined' ); + Koha::Patron::Categories->find($a_cat_code)->delete; +}; + $schema->storage->txn_rollback; 1; -- 2.1.4