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);