[Dbix-class] Shortcut to perform lookups

David Ihnen davidi at norchemlab.com
Tue Jul 7 01:19:07 GMT 2009


Dan Horne wrote:
>
> On 7/07/2009, at 12:43 PM, David Ihnen wrote:
>
>> Dan Horne wrote:
>>> Say I have a table called customer  which links to a parent table 
>>> called status. I wonder if there is a shortcut so that I don't need 
>>> to figure out the parent id in advance if I know the unique name.
>>>
>>> my $status = $self->schema->resultset('Status')->search({status_name 
>>> => 'new'})->single;
>>>
>>> my $customer = $self->schema->resultset->create({
>>>    name => 'Acme Corp',
>>>    status_id => $status->id
>>> })
>>>
>>
>> Like this?
>>
>> $self->schema->resultset('Status')->search({status_name => 
>> 'new'})->single->create_related( 'customer', { name => 'Acme Corp' } );
>>
>> You didn't put resultset('customer') in your second statement, btw.
>
> Whoops - I was trying to contrive an example without including all the 
> cruft of my code, which can lead to there kind of errors.
>
> Thanks for your response. It works well for one parent table. What I'm 
> really hoping to do is avoid writing code like this
>
>
> my $process = $self->schema->resultset('ETLProcess')->create({
>    name => $name,
>    status_id => $self->get_status_id($status_name),
>    phase_id => $self->get_phase_id($phase_name),
>    section_id => $self->get_section_id($section_name),
> });

I usually end up doing something vaguely like that, actually.  Only I'd 
name my rels status, phase, and section and do something like this...

I'll create 'create_process' method on the table class for the section - 
giving a pre-existing context for the creation of a process.  The status 
and phase of course will have to be passed in - but I like to handle 
them as objects instead of arbitrary id numbers, instantiated as early 
as possible in the request instead of trying to query for the id 
explicitly.  There's alot more you can do with an object than just an 
ID.  And put the modification sequence in a transaction.

sub create_process {
  my ($self, $status_obj, $phase_obj) = @_;
  $self->txn_do( sub { $self->create({ status => $status_obj, phase => 
$phase_obj }) } );
}

I don't know of any shortcuts beyond providing context for such 
operations, in this case this could be called a factory pattern where 
create_process is a factory for ETLProcess objects related to a 
particular section object.  The creation of a ETLProcess object requires 
the existance of status, phase, and section objects as part of it, so 
you're going to have to pull that off somehow.

David






More information about the DBIx-Class mailing list