In Laravel, how do I retrieve a random user_id from the Users table for Model Factory seeding data generation?
Asked Answered
N

8

36

Currently, in my ModelFactory.php, I have:

$factory->define(App\Reply::class, function (Faker\Generator $faker) {
  return [
    'thread_id' => 1,
    'user_id' => 1,
    'body' => $faker->paragraph
  ];
});

I would like to generate a random user_id from one of the user ID's already stored in the user table. I'm stumped because I don't know the way to display data output to code properly, and I was wondering how I would be able to allow Laravel to choose a random user ID and insert into the database. Thank you! :)

Niobium answered 21/5, 2017 at 22:38 Comment(3)
by not using Eloquent: jan.kneschke.de/projects/mysql/order-by-randSowers
If I understood you correctly, then you must have generated some users. you can use: $faker->numberBetween(1, 1000), or random_int(1, 1000) considering that you have 1000 users.Besprent
I see, yes I was thinking of what my options were. :)Niobium
J
90

Try the below.

use App\User; // Assuming this is your User Model class with namespace.

$factory->define(App\Reply::class, function (Faker\Generator $faker) {
  return [
    'thread_id' => 1,
    'user_id' => User::all()->random()->id,
    'body' => $faker->paragraph
  ];
});

Remember that this gets all the user data from your table and then choses an id randomly. So if your table has huge amount of data, it is not recommended. Instead, in your Test Case, you can create a new User (via its own factory) and assign the id to the Reply object generated from the above factory.

Alternately, you can query for a specific user in the above factory definition.

'user_id' => User::where('username', 'like', '[email protected]')->get()->random()->id

If you have a test user set up in your DB this will avoid pulling all the user data.

Jethro answered 21/5, 2017 at 22:46 Comment(6)
I typed in 'use App\User;' at the top of the file ModelFactory.php but when php artisan db:seed is run, 'user_id' shows up as none, what am I doing wrong?Niobium
Do you already have any user data in the DB that you are connecting to? If not, you can seed it using - factory(App\User::class, 5)->create(); so that there will be some user data. Make sure that you are seeding the user data before you try to seed your Reply dataJethro
yes, I have user id's from 51-131 pre-created. so I'm really wishing I'd be able to get a user_id randomly generated between that number as well. Right now I'm trying something like 'user_id' => factory('App\User')->all()->random()->user_id without much success, sorry, I'm a bit noob. :)Niobium
What is the column name for user's id in your users table in the database?Jethro
Anita, your as much a genius as I'm an idiot, yes, that was the problem, the column name is 'id' instead of 'user_id', now your code works perfectly. Thanks so much Anita! Cheers! :)Niobium
This is much faster: https://mcmap.net/q/417984/-in-laravel-how-do-i-retrieve-a-random-user_id-from-the-users-table-for-model-factory-seeding-data-generationMegaphone
M
17

Any class that extends Illuminate\Database\Eloquent\Model will be able to do this:

User::inRandomOrder()->first()

Or to get a Collection of 3 items:

User::inRandomOrder()->limit(3)->get()

This might be more efficient than using User::all()->first(), which ought to first query all Users.

Your IDE (like PhpStorm) will probably be wildly confused that this is an option though.

Also see: Laravel - Eloquent or Fluent random row

Mathers answered 17/10, 2019 at 11:53 Comment(1)
This is far better than the accepted answer. This doesn't pull the entire table into memory just to get one random record.Mercurial
T
5

It does not work like that 'user_id':

User::all()->random()->user_id

But that's how it works:

User::all()->random()->id
Tyro answered 20/3, 2019 at 17:50 Comment(2)
What are those wired **s called 🤷‍♂️?Maxinemaxiskirt
this "**" is not going hereTyro
N
3

It may not be that efficient but you can use it:

User::all('id')->random();

or

rand(1,User::count());

or

User::inRandomOrder()->limit(1)->get();

First one will be more faster than User::all()->random()->id; because that all function by default gets '*' as column name parameter. So, it will get all the columns for all the rows.

Nabors answered 28/8, 2020 at 6:21 Comment(0)
A
1

I personally like to use.

App\User::pluck('id')->random()

Change the model name which model you want

Arminius answered 16/5, 2020 at 11:12 Comment(0)
A
0

If Anyone wants a unique User_id you can try this.

'user_id' => User::all()->unique()->random()->id,

Or either it's

'user_id' => User::all()->random()->id,

Model name can change as your wants.

Arturo answered 19/2, 2022 at 13:8 Comment(0)
S
0

You can also create unique id this way

$factory->define(App\Reply::class, function (Faker\Generator $faker) {
  return [
    'thread_id' => 1,
    'user_id' => User::query()->inRandomOrder()->value('id'),
    'body' => $faker->paragraph
  ];
});
Shulman answered 10/2 at 12:27 Comment(0)
I
0

I prefer you go with this method

DB::table('users')->inRandomOrder()->value('id')

This method allows you to have more control and flexibility with emphasize on reduced query and memory usage

Intimidate answered 25/5 at 6:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.