2

I am using laravel factory method for populating my database table. I have three models and their relationship with each other are given below:

   **User model**

class User extends Authenticatable
{
    public function books() {
        return $this->hasMany('App\Book', 'user_id', 'id');
    }

    public function ratings() {
        return $this->hasMany('App\Rating', 'user_id', 'id');
    }
}


    **Book Model**

    class Book extends Model
{
    public function user() {
        return $this->belongsTo('App\User', 'user_id', 'id');
    }

    public function ratings() {
        return $this->hasMany('App\Rating', 'book_id', 'id');
    }

 **Rating Model**

class Rating extends Model
{

    public function book() {
        return $this->belongsTo('App\Book', 'book_id', 'id');
    }
    public function user() {
        return $this->belongsTo('App\User', 'user_id', 'id');
    }
}

And my factory definition for model Book and Rating look like this:

$factory->define(Book::class, function (Faker $faker) {
    return [
        'title' => $faker->title,
        'description' => $faker->sentence
    ];
});

$factory->define(Rating::class, function (Faker $faker) {
    return [
        'rating' => $faker->numberBetween(1,5)
    ];
});

Database table look like this:

User table:

id,name,email,password

Book table:

id,user_id,title,description

Rating table:

id,user_id,book_id,rating

The code for calling factory is given below:

public function run()
    {   
        //create 10 users
        $user = factory(App\User::class,10)->create();

        // create 2 books for each user
        $user->each(function ($user) {
            $book = $user->books()->saveMany(factory(App\Book::class,2)->make());
            });

        });

So with this run method i am able to create 10 users and each user have two books. But i also want to have each book rated by 3 different users. So what extra code should i add in above method to achieve this.

Milan Budhathoki
  • 61
  • 2
  • 3
  • 7

1 Answers1

2

I have a simple approaching method that you may consider

//create 10 users
$user = factory(App\User::class,10)->create();
$id_arr = Arr::pluck($user , 'id'); // get user id array

// create 2 books for each user
$user->each(function ($user) use($id_arr) {
    $books = $user->books()->saveMany(factory(App\Book::class,2)->make());
    $shuffle_id = Arr::shuffle($id_arr); // shuffle user_id each time create user successfully
    // add 3 rates for each book with different user
    $books->each(function ($book) use($shuffle_id) {
        $book_id = $book['id'];
        for ($i=0; $i<3; $i++){
            $user_id = $shuffle_id[$i]; // get id in first 3 of shuffle_id array (this will make sure, user_id will never be duplicated
            factory(App\Rate::class)->create(['book_id'=>$book_id, 'user_id' => $user_id]);
        }
    });
});

Hope it will help

Thien Huynh
  • 559
  • 5
  • 13
  • Only that i need to do is define array variable globally otherwise in each function it will say undefined variable. And other everything works fine. Thank u so much. – Milan Budhathoki Jun 15 '20 at 16:13
  • Yes, thank you, I forgot to use `use()` for passing parameter to the callback function. I will update my answer – Thien Huynh Jun 15 '20 at 21:19