In L-4 it was simple:
$random_quote = Quotation::all()->random(1);
But now in L-5 not a single method described in this post is working: Laravel - Eloquent or Fluent random row
My view file just gets blank.
In L-4 it was simple:
$random_quote = Quotation::all()->random(1);
But now in L-5 not a single method described in this post is working: Laravel - Eloquent or Fluent random row
My view file just gets blank.
These works but probably you didn't use the right namespace, just use the use statement at the top of your class name like this:
<?php namespace SomeNamespace;
use App\Quotation; // Says "Quotation.php" is in "App" folder (By default in L-5.0)
class someClass {
//...
}
Then you may use in your method something like this:
// You may add: use DB; at the top to use DB instead of \DB
$random_quote = Quotation::orderBy(\DB::raw('RAND()'))->first();
Or this:
$random_quote = Quotation::orderByRaw("RAND()")->first();
Update (Since Laravel - 5.2):
$random_quote = Quotation::inRandomOrder()->first();
random() gives error in 5.2, so instead u can use inRandomOrder https://laravel.com/docs/5.2/queries#ordering-grouping-limit-and-offset ,
and it works on Eloquent like
Model::inRandomOrder()->first()
Update for Laravel 5.4
New randomsorting in Laravel 5.4
->inRandomOrder()->first()
UPDATE FOR LARAVEL 5.3
I was happy to discover this is now a native query function! :D
The inRandomOrder method may be used to sort the query results randomly. For example, you may use this method to fetch a random user:
$randomUser = DB::table('users')
->inRandomOrder()
->first();
Unfortunately none of these answers make full use of Laravel 5's collections. If you came here from Google, like me, looking for a completely native solution please look below!
The Answer from The Alpha has the Database dependency flaw and Benjamin's, as he pointed out, may pose a problem when rows are removed in between. Highly unlikely, but still possible.
Here's a a one line solution to select random rows in Laravel 5+
// The setup
$numberOfRows = 4;
$models = Model::all(); // or use a ::where()->get();
// And the actual randomisation line
$randRows = $models->shuffle()->slice(0,numberOfRows);
Et voila - happy coding! Vote it up when you see it so it'll rise on the page :)
The orderByRaw('RAND()') has 2 issues:
Here is the solution i used, which seems to be a bit better:
$cnt = $records->count();
if ($cnt == 0)
return;
$randIndex = rand(0, $cnt-1);
$obj = $records->skip($randIndex)->take(1)->first();
EDIT: Please note that my solution may be a problem (crash if no luck) in case of parrallel requests to the database, if some records are deleted between the "count()" and the "skip()".
I'd implement this a little differently, using Benjamin's idea. A Query Scope for this feels appropriate so it's reusable, and it falls into your normal Eloquent use.
Note: In Eloquent 5.2, there is built in support for global scopes.
I'm going to create a trait that models can utilize, but you can just add the scopeRandom method directly to your specific model.
/app/GlobalScopes.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
trait GlobalScopes
{
public function scopeRandom($query){
$totalRows = static::count() - 1;
$skip = $totalRows > 0 ? mt_rand(0, $totalRows) : 0;
return $query->skip($skip)->take(1);
}
}
Then, each model you want to utilize the global scopes, name the trait inside the class.
/app/Quotation.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Quotation extends Model
{
use GlobalScopes;
//...
}
In use:
$randomQuote = \Quotation::random()->first();
In Laravel 5.1 (and Laravel 5.2) there is a random method in the Collection class returned by the Eloquent builder.
https://laravel.com/docs/5.1/collections#available-methods
So your call
$random_quote = Quotation::all()->random(1);
or
$random_quote = Quotation::where('column', 'value')->get()->random(1);
should work properly.
Laravel 5.4
1) if need one random model:
$object = Model::all()->random();
2) if need many random models:
$object = Model::all()->random($n); //$n - number of elements
//$object - collection
Comment: Calling $collection->random(1) will now return a new collection instance with one item.This method will only return a single object if no arguments are supplied.
Doc ref: https://laravel.com/docs/5.4/collections#method-random
orderByRaw('RAND()')
Note: It will take in ram all the rows from the rest of the query, so if you have a large table whithout other filters in the same query it will give bad performances, otherwise this is your option
You can use the random() method, which "returns a random item from the collection":
Product::where('city_id', $discount->product->city)
->get()
->random(1);