Reputation: 15
I have a Users table that acts as an abstract table for Engineers and Architects tables.
Users [id (PK), first_name, last_name, role]
where 'role' is either 'Engineer' or 'Architect'
Engineers [id (PK/FK), experience, skill_set]
where foreign 'id' references 'id' on 'Users'
Architects [id (PK/FK), certification, level]
where foreign 'id' references 'id' on 'Users'
(The table attributes are arbitrary. I just wanted to get the idea across. Basically there's two tables that share common attributes. The common attributes have been moved in to it's own table).
After I seed the Users table I need to seed the Engineers table with unique Id's matching Users table (since it's a PK and an FK) where Users.role == 'Engineer'.
The same must be done for Architects.
My current solution is to create Users, do a query to get all users where 'role' is 'Engineer' and in a foreach
statement create Engineers for each user.
class DatabaseSeeder extends Seeder
{
public function run()
{
$faker = Faker\Factory::create();
$users = factory(App\User::class, 10)->create(); // Create Users
$engineers = App\User::all()->where('role', 'engineer');
foreach($engineers as $engineer){
App\Engineer::create([
'id' => $engineer->id,
...
]);
}
}
}
How can move App\Engineer to it's own Seeder?
My thought process was to create an array of users where 'role' == 'engineer'. Then pop off a user and use that user's User->id when creating an Engineer.
class EngineersTableSeederextends Seeder
{
public function run()
{
$engineers = App\User::all()->where('role', 'engineer');
$engineer = array_pop( $engineers );
factory(App\Engineer::class, 10)->create()->each(function($e) {
//$p-> ; ???
});
}
}
I also tried this inside EngineerFactory;
use Faker\Generator as Faker;
$factory->define(App\Engineer::class, function (Faker $faker) {
return [
'id' => $faker->unique()->randomElement(App\User::all()->where('roles', 'engineer')->pluck('id')->toArray()),
...
];
});
However, because of the unique()
modifier I get a Maximum retries of 10000 reached without finding a unique value
error. It works if I have about a 100 Users but only create 10 Engineers.
I'm not sure if this is the right approach.
Upvotes: 0
Views: 1679
Reputation: 1844
id
should never be a foreign key, if your engineers
needs to be related to a user, create a user_id
field on engineers
table. Then your seeders will be:
$users = factory(App\User::class, 10)->create(); // Create Users
$usersEngineers = App\User::all()->where('role', 'engineer');
foreach($usersEngineers as $userEngineer){
App\Engineer::create([
'user_id' => $userEngineer->id,
...
]);
}
Or you can define your engineer factory like this:
use Faker\Generator as Faker;
$factory->define(App\Engineer::class, function (Faker $faker) {
$userEngineer = factory(App\User::class)->create();
// some logic to assign engineer role to $userEngineer
return [
'user_id' => $userEngineer
...
];
});
Upvotes: 1