title: Laravel 5.2 - caching, pagination and random order
body: <p>I have to display posts on multiple pages, but I want the order be always different. Unfortunately <code>inRandomOrder()</code> can give already displayed items by requesting another page, and <code>orderBy(DB::raw('RAND(aseed)')</code> or <code>orderByRaw('RAND(aseed)')</code> (with a session constant <code>aseed</code>) are database specific and slow on a big dataset. </p>
  
  <p>I decided to cache the array containing the ids of the posts to be displayed, then shuffle it and retrieve it for pagination.</p>
  
  <p>A simple example in tinker:</p>
  
  <pre><code>&gt;&gt;&gt;$posts_ids = Post::pluck('id')-&gt;shuffle();
  =&gt; Illuminate\Support\Collection {#835
   all: [
     8,
     6,
     1,
     2,
     4,
     7,
     3,
     5,
   ],
  }
  
  
  &gt;&gt;&gt;$sliced_ids = $posts_ids-&gt;slice(0,2)-&gt;all();
  =&gt; [
   8,
   6,
  ]
  
  &gt;&gt;&gt; Post::whereIn('id',$posts_ids-&gt;slice(0,2)-&gt;all())-&gt;get();
  
  =&gt; Illuminate\Database\Eloquent\Collection {#865
   all: [
     App\Post {#883
       id: 6,
       ...
     },
     App\Post {#881
       id: 8,
       ...
     }
   ],
   }
  </code></pre>
  
  <p>The posts returned by <code>whereIn</code> (also by <code>findMany</code>) method are in ascending order, 'cause is like to use a where clause <code>...WHERE id IN (6,8)</code>. One solution could be <code>orderByRaw('FIELD(id,$sliced_ids)</code>, but 
  the same holds true for <code>orderByRaw('RAND(aseed)')</code>...</p>
  
  <p>Is there an efficient way to have pagination with a consistent random order between pages?</p>
  
  <p><strong>EDIT: solution</strong></p>
  
  <p>I'm exploring the possibility to use <code>inRandomOrder</code>, cache the Eloquent Collection and rebuild it. Something like:</p>
  
  <pre><code> $posts = Cache::remember('posts', 30, function(){ 
       return serialize(Post::with('terms')-&gt;inRandomOrder()-&gt;get());
   });
   $posts = unserialize($posts);
  </code></pre>
  
  <p>In this case I think it's better to use <code>if (Cache::has('key')){...}</code> </p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I don't know if it can be depend to the redis connection type: on tcp I have to serialize and unserialize, while on unix socket it works without serialize/unserialize</p>