Veltro has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

The following is from the documentation at DBIx::Class::ResultSet which describes a populate method that can take an entire hash structure to populate related tables:

$schema->resultset("Artist")->populate([ { artistid => 4, name => 'Manufactured Crap', cds => [ { title => 'My First CD', year => 2006 }, { title => 'Yet More Tweeny-Pop crap', year => 2007 }, ], }, { artistid => 5, name => 'Angsty-Whiny Girl', cds => [ { title => 'My parents sold me to a record company', year => 200 +5 }, { title => 'Why Am I So Ugly?', year => 2006 }, { title => 'I Got Surgery and am now Popular', year => 2007 } ], }, ]);

I am basically looking for the inverse action of populate that instantly gives me a Perl hash with exactly 'that' format with the results from the database. In the following code I'll try to illustrate this with the method to_data that is a fictional method to demonstrate what I would like to achieve:

my $artistsAndTitles = $schema->resultset('Artist')-> search(...)->search_related_rs('cds', {...})->as_data # or another case using a accessor-method with the name 'cds' from a m +any_to_many relation: my $artistsAndTitles = $schema->resultset('Artist')-> cds()->as_data ;

The expected result that I hope for in $artistsAndTitles is a Perl array/hash construct like:

[ { artistid => 4, name => 'Manufactured Crap', cds => [ { title => 'My First CD', year => 2006 }, { title => 'Yet More Tweeny-Pop crap', year => 2007 }, ], }, { artistid => 5, name => 'Angsty-Whiny Girl', cds => [ { title => 'My parents sold me to a record company', year => 200 +5 }, { title => 'Why Am I So Ugly?', year => 2006 }, { title => 'I Got Surgery and am now Popular', year => 2007 } ], } ]

I done quite a bit of reading regards DBIx::Class but can't find a method to do this. Is there any method 'out-of-the-box' that can do this (correctly, taken different types of relations in account such as one-to-many or many-to-many)?

With best regards,

Veltro

Replies are listed 'Best First'.
Re: DBIx::Class::ResultSet disired hash output including related items
by spadacciniweb (Curate) on Feb 26, 2019 at 13:51 UTC
    If I have undestand, you have to use ResultClass::HashRefInflator
    An example in documentation page.

    ($_="nzz ojjdloobnf jjt tqqbebd77jojxfc")=~y~wb-zg2-5c96-8~aa-z0-9~s=~s~~~s;$_=~y~5-8~fuck~;print

      I have tried something like the following,

      my $artists = $schema->resultset('Artist') ; # $artists->result_class ('DBIx::Class::ResultClass::HashRefInflator'); # will cause errors my $artistAndTitles = $artists->next->cds() ; $artistAndTitles->result_class ('DBIx::Class::ResultClass::HashRefInflator'); while (my $hashref = $artistAndTitles->next) { print Dumper($hashref) ; }

      But this way I only get a 'shallow' hash from the 'cds' result subset for only one row at a time instead of each Artist + all the titles.

      Maybe there is another way? Examples appreciated.

        Documentation report:

        ... Specifying this class as a result_class for a resultset will change $rs->next to return a plain data hash-ref (or a list of such hash-refs if $rs->all is used

        so last lines of your code turn in
        my @hashref = $artistAndTitles->all; print Dumper(\@hashref) ;

        ($_="nzz ojjdloobnf jjt tqqbebd77jojxfc")=~y~wb-zg2-5c96-8~aa-z0-9~s=~s~~~s;$_=~y~5-8~fuck~;print