[Dbix-class] DBIx::Class::ResultSet::RecursiveUpdate - announcement and RFC

Jess Robinson castaway at desert-island.me.uk
Mon Sep 29 08:00:54 BST 2008



On Sun, 28 Sep 2008, Zbigniew Lukasiak wrote:

> On Sun, Sep 28, 2008 at 10:00 PM, Daniel Westermann-Clark <dwc at pobox.com> wrote:
>> On 2008-09-28 17:17:33 +0200, Zbigniew Lukasiak wrote:
>>> update_or_create relies on find - if you don't pass the PK - then
>>> find will issue an unrestricted search and return a random row (and
>>> issue the warning), then that random row will be updated, create
>>> will never be called.  This is assuming you add { key => primary} -
>>> if you don't do that then find will fall back to the old behaviour
>>> and also return a random row.
>>
>> That's also assuming you don't have any other unique constraints
>> defined. At least, that's how it was designed.
>
>
> That is a bit more complicated - you need to also have all columns of
> that constraint in the query.   So update_or_create works on tables
> with auto_increment keys only if you have an additional unique
> constraint in that table and use it in the query.

When you write that, doesn't it stop and make you think? If you have to 
contrive a query like the one below, that is attempting to update a row, 
if and only if we find a single match based on a column that isn't 
constrained to be unique.. Then surely that makes no sense? That code is a 
development-time error, and the dev should see it as such and fix: either 
add a unique constraint for the field they're trying to magically update 
based on, or add the columns for a unique constraint.

find is designed for unique constraints, so is update_or_create, there's 
really no point in using u_or_c if you're not operating on one, 
using/passing all the values for a particular constraint, that's just 
broken code.

> my $art2 = $cd_rs->update_or_create( { year => '1999' } );
> print "equals\n" if $art1->id == $art2->id;

Of course it fails.

Jess




More information about the DBIx-Class mailing list