From 2f9a92c13d8205e423df942dcf003d719f1ec95b 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 Signed-off-by: Nick Clemens --- 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 cf55089..c6bfede 100644 --- a/Koha/Object.pm +++ b/Koha/Object.pm @@ -57,8 +57,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 46348e4..2f206c3 100644 --- a/t/db_dependent/Koha/Objects.t +++ b/t/db_dependent/Koha/Objects.t @@ -19,11 +19,13 @@ use Modern::Perl; -use Test::More tests => 7; +use Test::More tests => 8; use Test::Warn; use Koha::Authority::Types; use Koha::Cities; +use Koha::Patron::Category; +use Koha::Patron::Categories; use Koha::Patrons; use Koha::Database; @@ -80,6 +82,17 @@ subtest 'not_covered_yet' => sub { plan tests => 1; warning_is { Koha::Patrons->search->not_covered_yet } { carped => 'The method not_covered_yet is not covered by tests' }, "If a method is not covered by tests, the AUTOLOAD method won't execute the method"; }; +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