Reputation: 1998
Is there any way to run a laravel seed
to only insert the records if they do not exist already?
My current laravel seeder looks like this
DB::table('users')->insert([
//Global Admin
[
'member_id' => 11111111,
'firstname' => 'Joe',
'lastname' => 'Bloggs'
],
[
'member_id' => 22222222,
'firstname' => 'Jim',
'lastname' => 'Bloggs'
],
]);
Pretty standard!
would I have to wrap each and every insert in a try catch? like this
try {
DB::table('users')->insert(['member_id' => 11111111, 'firstname' => 'Joe', 'lastname' => 'Bloggs']);
} catch(Exception $e){
//Die silently
}
try {
DB::table('users')->insert(['member_id' => 22222222, 'firstname' => 'Jim', 'lastname' => 'Bloggs']);
} catch(Exception $e){
//Die silently
}
Later on I might want to add extra rows to the same seeder without having to write a new one, and re run php artisan db:seed
to only add my new rows.
Is this possible?
Upvotes: 4
Views: 12692
Reputation: 407
As stokoe0990 stated, it is not advisable to run seeders in production. The Laravel Seeder was written as way to generate test data. Per the documentation "Laravel includes a simple method of seeding your database with test data using seed classes".
That said, The only way you can satisfy your question is to build the logic into your seed:
$users = array(
['member_id' => 11111111,'firstname' => 'Joe','lastname' => 'Bloggs'],
['member_id' => 22222222,'firstname' => 'Jim','lastname' => 'Bloggs']
);
foreach ($users as $user) {
if (\App\User::find($user['id'])) {
DB::table('users')->insert($user);
}
}
Upvotes: 3
Reputation: 3594
The best I recommend is to truncate (or delete all) the data in the table anytime you migrate. Try something like this:
//data in the table
DB::table('users')->delete(); //or use model like this: User::truncate();
DB::table('users')->insert([
//Global Admin
[
'member_id' => 11111111,
'firstname' => 'Joe',
'lastname' => 'Bloggs'
],
[
'member_id' => 22222222,
'firstname' => 'Jim',
'lastname' => 'Bloggs'
],
]);
Then there will be no duplications when you run php artisan db:seed
Upvotes: 1
Reputation: 5088
You can achieve this by Eloquent firstOrCreate.
The firstOrCreate method will attempt to locate a database record using the given column / value pairs. If the model can not be found in the database, a record will be inserted with the attributes from the first parameter, along with those in the optional second parameter.
So, if you identify the user by member_id, you can do something like this:
User::firstOrCreate(
['member_id' => 11111111],
[
'firstname' => 'anakin',
'lastname' => 'skywalker',
'password' => Hash::make('4nak1n')
]
);
If you want to locate the record by 'member_id', 'firstname' and 'lastname' fields, something like this:
User::firstOrCreate(
[
'member_id' => 11111111,
'firstname' => 'anakin',
'lastname' => 'skywalker'
],
[
'password' => Hash::make('4nak1n'),
]
);
Upvotes: 8
Reputation: 3951
You can achieve that by using Eloquent updateOrInsert()
method:
DB::table('users')->updateOrInsert('your_data');
Read more about it here.
Upvotes: 1
Reputation: 473
Seeding is only supposed to be used for testing, anyways.
Why don't you just execute php artisan migrate:fresh --seed
?
This will refresh your database (deletes the tables) then runs all your migrations again and finally seeds the database again.
You should never be using seeders in production.
Just add the new data to your seeder, run migrate:fresh
and re-seed :)
Upvotes: 3