deep using the same syntax as a multi-step join:
my $rs = $schema->resultset('Tag')->search(
- undef,
+ {},
{
prefetch => {
cd => 'artist'
my $tag = $rs->first;
print $tag->cd->artist->name;
+=head2 Columns of data
+
+If you want to find the sum of a particular column there are several
+ways, the obvious one is to use search:
+
+ my $rs = $schema->resultset('Items')->search(
+ {},
+ {
+ select => [ { sum => 'Cost' } ],
+ as => [ 'total_cost' ],
+ }
+ );
+ my $tc = $rs->first->get_column('total_cost');
+
+Or, you can use the L<DBIx::Class::ResultSetColumn>, which gets
+returned when you ask the C<ResultSet> for a column using
+C<get_column>:
+
+ my $cost = $schema->resultset('Items')->get_column('Cost');
+ my $tc = $cost->sum;
+
+With this you can also do:
+
+ my $minvalue = $cost->min;
+ my $maxvalue = $cost->max;
+
+Or just iterate through the values of this column only:
+
+ while ( my $c = $cost->next ) {
+ print $c;
+ }
+
+ foreach my $c ($cost->all) {
+ print $c;
+ }
+
+C<ResultSetColumn> only has a limited number of built-in functions, if
+you need one that it doesn't have, then you can use the C<func> method
+instead:
+
+ my $avg = $cost->func('AVERAGE');
+
+This will cause the following SQL statement to be run:
+
+ SELECT AVERAGE(Cost) FROM Items me
+
+Which will of course only work if your database supports this function.
+See L<DBIx::Class::ResultSetColumn> for more documentation.
+
=head2 Using relationships
=head3 Create a new row in a related table
methods into the Admin class. There is a cleaner way to accomplish
this.
-Overriding the C<inflate_results()> method within the User proxy-class
+Overriding the C<inflate_result> method within the User proxy-class
gives us the effect we want. This method is called by
L<DBIx::Class::ResultSet> when inflating a result from storage. So we
grab the object being returned, inspect the values we are looking for,
### The statement below will print
print "I can do admin stuff\n" if $admin->can('do_admin_stuff');
+=head2 Skip object creation for faster results
+
+DBIx::Class is not built for speed, it's built for convenience and
+ease of use, but sometimes you just need to get the data, and skip the
+fancy objects. Luckily this is also fairly easy using
+C<inflate_result>:
+
+ # Define a class which just returns the results as a hashref:
+ package My::HashRefInflator;
+
+ ## $me is the hashref of cols/data from the immediate resultsource
+ ## $prefetch is a deep hashref of all the data from the prefetched
+ ## related sources.
+
+ sub mk_hash {
+ my ($me, $rest) = @_;
+
+ return { %$me,
+ map { ($_ => mk_hash(@{$rest->{$_}})) } keys %$rest
+ };
+ }
+
+ sub inflate_result {
+ my ($self, $source, $me, $prefetch) = @_;
+ return mk_hash($me, $prefetch);
+ }
+
+ # Change the object inflation to a hashref for just this resultset:
+ $rs->result_class('My::HashRefInflator');
+
+ my $datahashref = $rs->next;
+ foreach my $col (keys %$datahashref) {
+ if(!ref($datahashref->{$col}) {
+ # It's a plain value
+ }
+ elsif(ref($datahashref->{$col} eq 'HASH')) {
+ # It's a related value in a hashref
+ }
+ }
+
+=head2 Want to know if find_or_create found or created a row?
+
+Just use C<find_or_new> instead, then check C<in_storage>:
+
+ my $obj = $rs->find_or_new({ blah => 'blarg' });
+ unless ($obj->in_storage) {
+ $obj->insert;
+ # do whatever else you wanted if it was a new row
+ }
+
=cut