start_cache in CodeIgniter Active Record for repeated query parts

CodeIgniter’s Active Record resets itself after every get(), which is what you want almost always and a nuisance exactly once per paginated listing: the total and the page of rows need the same joins and the same conditions, so they get written out twice and then drift apart. start_cache() marks everything up to stop_cache() as sticky.

$this->db->start_cache();
$this->db->from('orders')
         ->join('customers', 'customers.id = orders.customer_id')
         ->where('orders.status', 'paid');
$this->db->stop_cache();

$total = $this->db->count_all_results();
$rows  = $this->db->limit(20, $offset)->get()->result();

$this->db->flush_cache();

The catch is the flush. Cached parts survive not merely the next query but every query for the rest of the request, so leaving flush_cache() out produces a bug that looks impossible from where it surfaces: some later, unrelated get() comes back filtered by a where that is nowhere near it. I have taken to writing the three calls as one block and deciding where the flush goes before writing anything in between. It caches the query being built and nothing else — the results are not cached by any of this.