Search code examples
phplaravellaravel-5.3

laravel factory insert foreign key


Hello everyone who's trying to help,

im trying to create the factory file to seeding my database and i have a question how can i insert a foreign key from a table already seeded ? and the factory code is to have all in same file? any good pratice to this ?

Files

Model User

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{

  protected $table = 'user'; //name of the table in database
  protected $primaryKey = 'Id'; //Primary Key of the table

  /**
   * Relations between tables
   */
   public function GetLoginInfo()
   {
     return $this->hasMany('App\Models\LoginInfo', 'UserId');
   }

   public function getStatus()
   {
     return $this->belongsTo('App\Models\AccountStatus');
   }

}

Model Account status

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class AccountStatus extends Model
{
  protected $table = 'account_status'; //name of the table in database
  protected $primaryKey = 'Id'; //primary Key of the table
  public $timestamps = false; //true if this table have timestaps
  /**
   * Relations between tables
   */
   public function GetUsers()
   {
     return $this->hasMany('App\Models\Users', 'StatusId');
   }
}

factory file:

<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */

//Factory for Account Status table
$factory->define(App\Models\AccountStatus::class, function (Faker\Generator $faker) {
    return [
      'Description' => $faker->word,
    ];
});

//Factory for user table
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
    return [
      'Username' => $faker->unique()->userName,
      'Password' => bcrypt('test'),
      'Email' => $faker->unique()->safeEmail,
      'Name' => $faker->name,
      'StatusId' => Factory(App\Models\AccountStatus::class)->create()->id,
    ];
});

This is what im trying to do as you can see : Factory(App\Models\AccountStatus::class)->create()->id but don't work


Solution

  • $factory->define(App\Models\User::class, function (Faker\Generator $faker) {
        return [
          'Username' => $faker->unique()->userName,
          'Password' => bcrypt('test'),
          'Email' => $faker->unique()->safeEmail,
          'Name' => $faker->name,
          'StatusId' => factory(App\Models\AccountStatus::class)->create()->id,
        ];
    });
    

    i see an uppercase F in factory..

    $factory->define(App\Models\User::class, function (Faker\Generator $faker) {
    
         $accountStatus = factory(App\Models\AccountStatus::class)->create()
    
         return [
          'Username' => $faker->unique()->userName,
          'Password' => bcrypt('test'),
          'Email' => $faker->unique()->safeEmail,
          'Name' => $faker->name,
          'StatusId' => $accountStatus->id,
        ];
    });
    

    Edit (Improvement)

    If you have one model that depend on another model. you can do it this way, using a callback function to create with the related.

    Like this

    $factory->define(App\Models\User::class, function (Faker\Generator $faker) {
        return [
          'Username' => $faker->unique()->userName,
          'Password' => bcrypt('test'),
          'Email' => $faker->unique()->safeEmail,
          'Name' => $faker->name,
          'StatusId' => function () {
              return factory(App\Models\AccountStatus::class)->create()->id;
           }
        ];
    });
    

    One thing you need to keep in mind is that this will go to an endless loop if the related(Status Model) has a model that depends on the parent(User Model).