From: Peter Rabbitson Date: Thu, 13 Aug 2015 09:40:55 +0000 (+0200) Subject: Add missing deprecation warnings on m2m set_*, tighten up code X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=8a67d9cf41e498c6e2fe7d79051d402cba4b7ec8;p=dbsrgits%2FDBIx-Class.git Add missing deprecation warnings on m2m set_*, tighten up code Back in the day 4d3a827d had the right idea but did not implement actual deprecation carp()s. Then ac36a402 added support for a link-data arg, making things even murkier... sigh. --- diff --git a/Changes b/Changes index 79647e8..e4b1733 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ Revision history for DBIx::Class an underlying search_rs(), as by design these arguments would be used only on the first call to ->related_resultset(), and ignored afterwards. Instead an exception (detailing the fix) is thrown. + - Calling the set_* many-to-many helper with a list (instead of an + arrayref) now emits a deprecation warning * New Features - DBIx::Class::Optional::Dependencies now properly understands diff --git a/lib/DBIx/Class/Relationship/ManyToMany.pm b/lib/DBIx/Class/Relationship/ManyToMany.pm index 6dfa22e..c5f4570 100644 --- a/lib/DBIx/Class/Relationship/ManyToMany.pm +++ b/lib/DBIx/Class/Relationship/ManyToMany.pm @@ -108,9 +108,28 @@ EOW my $set_meth_name = join '::', $class, $set_meth; *$set_meth_name = subname $set_meth_name, sub { + my $self = shift; - @_ > 0 or $self->throw_exception( - "{$set_meth} needs a list of objects or hashrefs" + + my $set_to = ( ref $_[0] eq 'ARRAY' ) + ? ( shift @_ ) + : do { + carp_unique( + "Calling '$set_meth' with a list of items to link to is deprecated, use an arrayref instead" + ); + + # gobble up everything from @_ into a new arrayref + [ splice @_ ] + } + ; + + # make sure folks are not invoking a bizarre mix of deprecated and curent syntax + $self->throw_exception( + "'$set_meth' expects an arrayref of objects or hashrefs to link to, and an optional hashref of link data" + ) if ( + @_ > 1 + or + ( @_ and ref $_[0] ne 'HASH' ) ); my $guard = $self->result_source->schema->storage->txn_scope_guard; @@ -124,8 +143,10 @@ EOW $self->search_related( $rel, {} )->delete; } # add in the set rel objects - $self->$add_meth($_, ref($_[1]) ? $_[1] : {}) - for ( ref($_[0]) eq 'ARRAY' ? @{ $_[0] } : @_ ); + $self->$add_meth( + $_, + @_, # at this point @_ is either empty or contains a lone link-data hash + ) for @$set_to; $guard->commit; }; diff --git a/t/relationship/core.t b/t/relationship/core.t index e0e243c..21ce508 100644 --- a/t/relationship/core.t +++ b/t/relationship/core.t @@ -3,6 +3,7 @@ use warnings; use Test::More; use Test::Exception; +use Test::Warn; use lib qw(t/lib); use DBICTest ':DiffSQL'; @@ -190,11 +191,18 @@ is( $prod_rs->first->name, 'Testy McProducer', 'many_to_many add_to_$rel($hash) ok' ); $cd->add_to_producers({ name => 'Jack Black' }); is( $prod_rs->count(), 2, 'many_to_many add_to_$rel($hash) count ok' ); -$cd->set_producers($schema->resultset('Producer')->all); -is( $cd->producers->count(), $prod_before_count+2, - 'many_to_many set_$rel(@objs) count ok' ); -$cd->set_producers($schema->resultset('Producer')->find(1)); -is( $cd->producers->count(), 1, 'many_to_many set_$rel($obj) count ok' ); + +warnings_like { + $cd->set_producers($schema->resultset('Producer')->all); + is( $cd->producers->count(), $prod_before_count+2, + 'many_to_many set_$rel(@objs) count ok' ); + + $cd->set_producers($schema->resultset('Producer')->find(1)); + is( $cd->producers->count(), 1, 'many_to_many set_$rel($obj) count ok' ); +} [ + ( qr/\QCalling 'set_producers' with a list of items to link to is deprecated, use an arrayref instead/ ) x 2 +], 'Warnings on deprecated invocation of set_* found'; + $cd->set_producers([$schema->resultset('Producer')->all]); is( $cd->producers->count(), $prod_before_count+2, 'many_to_many set_$rel(\@objs) count ok' ); diff --git a/t/relationship/custom.t b/t/relationship/custom.t index 058636b..b9bf5fa 100644 --- a/t/relationship/custom.t +++ b/t/relationship/custom.t @@ -301,7 +301,7 @@ for (qw( artist_limited_rank artist_limited_rank_opaque )) { ); # can't use the opaque one - need set_from_related to work - $artwork->set_artist_limited_rank( @artists ); + $artwork->set_artist_limited_rank( \@artists ); { local $TODO = 'Taking into account the relationship bridge condition is not likely to ever work... unless we get DQ hooked somehow';