[Dbix-class] order_by interfering with has_many fetch

Darin McBride darin.mcbride at shaw.ca
Sat Nov 14 21:46:42 GMT 2015


I'm getting an error message similar to an earlier message, 
http://lists.scsys.co.uk/pipermail/dbix-class/2014-August/011746.html 

I've got code like this:

        $planet_rs =
            Lacuna->db->resultset('Map::Body')->
            search(
                   {
                       'sitterauths.sitter_id' => $real_empire->id,
                       'me.class' => { '!=' => 
'Lacuna::DB::Result::Map::Body::Planet::Station' },
                   },
                   {
                       join => { empire => 'sitterauths' },
                       prefetch => 'empire',
                       order_by => ['me.name'],
                   });

It's giving me the same error:

DBIx::Class::ResultSet::_construct_results(): Unable to properly collapse 
has_many results in iterator mode due to order criteria - performed an eager 
cursor slurp underneath. Consider using ->all() instead at /data/Lacuna-
Server/lib/Lacuna/DB/Result/Empire.pm line 622

The earlier message implied that it would be fixed in 0.082700_05, but I'm 
using 0.082810 at the moment.  So, either it wasn't fixed, or I'm encountering 
something different.

Further searching uncovers https://www.mail-archive.com/dbix-class@lists.scsys.co.uk/msg07082.html - in which Peter Rabbitson indicates 
that I would 'need to order_by "leftmost part" for this message to go away' -- 
but I don't understand what "leftmost part" means in this context.

If it helps, Map::Body has 0 or 1 empires (can be null), and sitterauths has a 
dual-column primary key, referring to two empire through their IDs.  So, while 
ordering by empire is neither helpful nor hurtful to me, ordering by 
sitterauth makes no sense (though it will likely not harm me, either, if I 
sort in there).  However, I've tried an order_by of [ 'empire.id', 'me.name' 
], or even [ 'empire.id','sitterauths.sitter_id','me.name' ], and still end up 
with the error message.

I'm expecting that once I roll this out into production and it gets wide use, 
we'll have a thousand rows ("Map::Body" objects) being returned, and up to 40 
or 50 empires, so I'd rather not resort to ->all to save some memory in the 
Plack processes.

Any guidance on how to update this order_by to get DBIC to only fetch one row 
at a time would be appreciated.



More information about the DBIx-Class mailing list