Search code examples
laravelseeding

Seeding to populate a table with mandatory and random data


The goal is to populate a table with mandatory and random menu items.

The following case works fine with just random items

Parent table

$parents = [
   ['id' => 1, 'parent' => 'AA'],
   ['id' => 2, 'parent' => 'BB'],
   ['id' => 3, 'parent' => 'CC'],
];

Populate menus table

$menus = [
   ['id' => 1, 'menu' => 'A'],
   ['id' => 2, 'menu' => 'B'],
   ['id' => 3, 'menu' => 'C'],
   ['id' => 4, 'menu' => 'D'],
   ['id' => 5, 'menu' => 'E'],
];

foreach ($menus as $menu) {
   modelMenu::updateOrCreate([ 'id' => $menu['id']], $menu);
}

Relashionships

    $menus = Menu::all();

    Parent::all()->each(function ($parent) use ($menus) { 
        $parent->menus()->attach(
            $menus->random(rand(1, 5))->pluck('id')->toArray()
        ); 
    });

MODELS

class Parent extends Model
{
   protected $fillable = ['parents'];

   public function menus()
   {
     return $this->hasMany(Menu::class);
   }
}

 class Menu extends Model
 {
  protected $fillable = ['menus'];

  public function parents()
  {
    return $this->belongsTo(Parent::class);
  }
}

What i intend to achieve is that each parent must have related the ids 1 and 2 menus;

Menus 3, 4 and 5 are added randomly.

Example:

Parent AA - menus with ids 1, 2, 5; 
Parent BB - menus with ids 1, 2, 4, 6;
Parent CC - menus with ids 1, 2, 3;

Solution

  • This should achieve your desired result:

    
    $menus = Menu::all()->values();
    
    Parent::all()->each(function ($parent) use ($menus) { 
        $parent->menus()->attach([
            $menus->get(0)->id, 
            $menus->get(1)->id, 
            ...$menus->whereNotIn('id', [1,2])->random(rand(1, 5))->pluck('id')
        ]); 
    });
    
    
    

    The values() method returns a new collection with the keys, You can utilize to get the first and second records using the get(index) the rest basically get's random records and whereNotIn('id', [1,2]) skips the records with the ids [1, 2].