[Dbix-class] updating multiple records at once

Jonathan Rockway jon at jrock.us
Sun Jan 27 06:00:33 GMT 2008


Jonathan Rockway <jon at jrock.us> writes:

> If this is a frequent operation, write a method in your ResultSet
> class to do it.  Actually, you should do that anyway :)

This is worth clarifying:

  package SomeResultSet;
  use base 'DBIx::Class::ResultSet';

  sub get_things_that_you_want_to_manipulate {
      my ($self) = @_;
      return $self->search({ needs_to_be_updated_somehow => 1 });
  }

  sub do_that_query_you_described {
      my ($self) = @_;
      
      my $fantastic = $self->search({ fantastic => 1 });
      my $pending   = $self->search({ pending   => 1 });
      
      $self->result_source->storage->txn_do(sub {
          $fantastic->update({ amazing => 1 });
          $pending->update({ pending => 0, approved => 1 });
      });
  }

Then you can do this:

  $schema->resultset('SomeResultSet')->
      get_things_that_you_want_to_manipulate->
      do_that_query_you_described;

The idea is that you can chain resultsets, and that this is a good way
to abstract out your queries (and look at how reusable they are, you
could easily say:

  $rs->get_things_that_you_want_to_manipulate->update({foo => 'bar'}) 

if you wanted).

One point of clarification in case you missed this, you can call
search as many times as you want (to pare down the results).  That's
how we do this; in get_things_that_you_want_to_manipulate we get the
records that are either pending or fantastic, then in
do_that_query_you_described we "split" the result of
get_things_that_you_want_to_manipulate into the pieces to update, then
we do the update in a transaction.  Clean!

This sort of thing is what makes DBIC "a tool that I can't live
without" rather than "some neat syntactic sugar". :)

Regards,
Jonathan Rockway




More information about the DBIx-Class mailing list