Laravel 5.1 foreign keys in model factory
Asked Answered
C

2

7

How do you define foreign keys in a model factory. For example if I have a organisations table which has a foreign key to the countries table, in my model factory I'm having to define a dummy value for the country id as follows:

$factory->define(App\Organisation::class, function ($faker) {
   return [
      'name' => $faker->company,
      'country_id' => 197,
   ];
});

In my organisations table seeder class I am doing the following but the faker object isn't present - do I need to create a new faker object in my seeder class?

use Illuminate\Database\Seeder;

class OrganisationsTableSeeder extends Seeder
{

   public function run()
   {
      $countryIds = Country::lists('id')->all();

      factory('App\Organisation', 3)->create([
        // override factory default
        'country_id' => $faker->randomElement[$countryIds],
    ]);
   }
}

Database seeder class

class DatabaseSeeder extends Seeder
{
     public function run()
     {

        Model::unguard();

        $this->call('CountriesTableSeeder');
        $this->call('OrganisationsTableSeeder');

        Model::reguard();
     }
}

Whats the best way to define the foreign keys when defining model factories? Is it possible to omit the country_id from the model factory and add it in the seeder class instead - from the documention it seems you can only override an existing value defined in the model factory but you cant add a new value via the seeder class - correct me if i'm wrong?

Counterstroke answered 6/9, 2015 at 15:56 Comment(0)
A
2

I may be a bit late on this one but I was having the same issue, this fixed it for me. You should be able to do

$factory->define(App\Organisation::class, function ($faker) {
    return [
      'name' => $faker->company,
      'country_id' => factory(App\Country::class)->create()->id,
    ];
});

and then in your seed you just need to call

factory(App\Organisation::class, 5)->create();

and it will create the countries for you as well.

Activity answered 2/10, 2015 at 12:45 Comment(2)
The problem with this solution is that each organization will have one different country and it will never use an existing one, right?Davison
mmmmh, it's been a while since I wrote this code, but your observation seems correct, although I didn't really care about using an existing country at the time I wrote it.Activity
L
0

The way that the Laravel team, Otwell, Stauffer et.al., suggest is like this.

Testing > Adding Relations To Models

Adding relationships to your models

ModelFactory.php

$factory->define(App\Organisation::class, function ($faker) {
   return [
      'name' => $faker->company,
      'country_id' => 197,
   ];
});

$factory->define(App\Country::class, function ($faker) {
   return [
      'name' => $faker->country,
   ];
});

seeder

$organisations = factory('App\Organisation', 3)
  ->create()
  ->each(function($$organisation) {
      $organisation->relatedItems()->save(factory('App\Country')->make());
  });
Lucrece answered 5/10, 2015 at 17:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.