-
Notifications
You must be signed in to change notification settings - Fork 0
Building the Data Model Rolling Back & Resetting Migration, Creating Database Seeders
So right now we’ve run our migrations, we have these two tables in the database, and that’s great, we can move forward with our project, but I want to take some time to show you some other features that are built in to Laravel that help you manage these on a continuous basis. So we have these two tables that were part of a single migration and so sometimes you might want to roll back that migration, right? So the Artisan toolkit offers a way to do that. So if we actually want to go pull that back down, go back one migration, which is in this case is actually just one step anyway, we can run PHP Artisan migrate and then add rollback. There’s a separate command in there called rollback, and when you run that it will actually go through and remove those migrations. Before you execute the command below make sure you do have your servers running.
Adarsh:product-service adarshmaurya$ php artisan migrate:rollback
Rolling back: 2018_11_26_234437_create_descriptions_table
Rolled back: 2018_11_26_234437_create_descriptions_table
Rolling back: 2018_11_26_233429_create_product_table
Rolled back: 2018_11_26_233429_create_product_tableIt just goes back one step and gets rid of them. There’s another alternative which is reset. Reset is going to be rollback forever.
So rollback is just going to be one at a time. Reset’s going to take you all the way back.
Let's migrate our database again.
Adarsh:product-service adarshmaurya$ php artisan migrate
Migrating: 2018_11_26_233429_create_product_table
Migrated: 2018_11_26_233429_create_product_table
Migrating: 2018_11_26_234437_create_descriptions_table
Migrated: 2018_11_26_234437_create_descriptions_tableSo if we migrate our database again, we’ve created our tables, we can actually do PHP Artisan reset, and that’s going to get us PHP Artisan migrate reset, that’s going to take us all the way back.
Adarsh:product-service adarshmaurya$ php artisan migrate:reset
Rolling back: 2018_11_26_234437_create_descriptions_table
Rolled back: 2018_11_26_234437_create_descriptions_table
Rolling back: 2018_11_26_233429_create_product_table
Rolled back: 2018_11_26_233429_create_product_tableSo, for our demonstration is difficult because we only have one migration that we’re dealing with, but that’ll take you all the way back, and if you want to go all the way back and then build right back up to where you need to be, there’s an additional one called refresh, that will do that for you.
Adarsh:product-service adarshmaurya$ php artisan migrate:refresh
Nothing to rollback.
Migrating: 2018_11_26_233429_create_product_table
Migrated: 2018_11_26_233429_create_product_table
Migrating: 2018_11_26_234437_create_descriptions_table
Migrated: 2018_11_26_234437_create_descriptions_tableSo when we run it, we’ve already reset, we’ve already rolled back, it says there’s nothing to migrate, or nothing to roll back, and then it actually has migrated our tables again.
So we mentioned a little bit about seeds, seeding the database. These are pieces of infrastructure that are part of the project that let you actually define some pre-data that you want to be inside the database whenever you’re actually either deploying the code or for testing purposes.
I usually use them, especially when I’m building a service, I build them to seed the database with a lot of values that I might need, so that I can, again, testing the service really quickly. So Artisan has some commands that you can use to help us generate those seeders, which we’ll run right now.
So again, we can do PHP Artisan. We go into our make namespace, and then we look for a seeder and so all we need here is just to name the seeder, so we’re going to do a product table seeder. So because the products are kind of the key of all this, I just want to make sure that we can put a few values in there.
Adarsh:product-service adarshmaurya$ php artisan make:seeder ProductTableSeeder
Seeder created successfully.So we run that and it says seeder created successfully. We can go look at our code and go see those. So inside of that database directory, there’s migrations, which we’ve been looking at, but there’s also a seeds directory, and inside here we have our ProductTableSeeder. So this is included in the project, but as of right now is not actually active, it’s not doing very much.
<?php
use Illuminate\Database\Seeder;
class ProductTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//
}
}So there’s a class that already exists in the project, whenever you install it, called DatabaseSeeder, and inside here there’s a run method, and you can see that it comes stock with a commented out command to actually run a user TableSeeder. And what we want to do is just include ours. So we created a Product TableSeeder.
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
$this->call(ProductTableSeeder::class);
}
}And that run function is what’s going to be called when you’re doing the reset Or the refresh rather?
Yes, so whenever you’re actually using the command line to run your seeds, there’s a separate db namespace that you can actually say okay I want to run the seed method to actually go in and put the data in there. So when you do refresh you can actually include an extra option that would like force it to go in and say run, kill everything back down to nothing, go to right back up and include the seeds that are configured. But anything inside of the run method, inside of this database seeder class is just going to run. So this is kind of way to control what’s going to happen.
So right now we’ve created our ProductTableSeeder class. It’s currently empty, but we’ve told the framework that we want it to run whenever we run our seed method. And so what we want to do is just populate it with a little bit of code that will help us actually build some value.
I’ve just included some values for our run method within our product table seeder that will go through and populate the database with a few pre-built products for us.
<?php
use Illuminate\Database\Seeder;
class ProductTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$products =['beats', 'meats', 'greets'];
array_map(function($name){
$now = date('Y-m-d H:i:s', strtotime('now'));
DB::table('products')->insert([
'name' => $name,
'created_at' => $now,
'updated_at' => $now,
]);
});
}
}If we take a look at what’s been included here, we’ve just got an array that we’ve said is products variable that includes three product names. We have beats, meats and greets. And then we have an array map method that’s just going to go through and iterate over that array and then create the data inside of the database. And so when we take a look at what that method actually does, we’re creating a timestamp that is for now, so that we can put that in. And then we’re actually just putting the name in. So what it’s going to do when we run this, is it’s going to go through, it’s going to loop through this, go through all three of the values in our array, and it’s going to make three insert statements in the database and we should see beats, meats, greets.
Adarsh:product-service adarshmaurya$ php artisan db:seed
Seeding: ProductTableSeeder
Database seeding completed successfully.
Adarsh:product-service adarshmaurya$ Please note if there is an exception try running composer dump-autoload
Adarsh:product-service adarshmaurya$ ../composer.phar dump-autoload
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: beyondcode/laravel-dump-server
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.So to make, to actually run a seeder, just by itself, you do PHP Artisan db namespace and then seed, and then what this is going to do is it’s actually just going to go through and run everything that’s inside of the database seeder so you can see that it said seeded, product table seeder, and if we go back and look at our database, you can see that we have our products table and we’ll look at the content and you can see here that we have beats, meats and greets already in the database.
The thing that’s different about this than with the migrations is that every time you seed it always inserts. If you want it to be more complex, if you wanted it to be aware of what data’s in there and decide if it should include them or not, you can certainly use this db, it’s a facade inside of Laravel to check to see okay, I want to see is there already a product called beats? If there is don’t insert another one, but as it is right now we could run that command several times and what we would have is many records with those exact same values in them.
So one of the other downfalls of just doing PHP Artisan db seed is that it’s just going to run everything that’s been configured inside of that main database seeder. If we decided, for instance, that we didn’t want to seed product data every time we seeded, we could remove this,
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
//$this->call(ProductTableSeeder::class);
}
}This call to say okay every time we run the database seeder, run the product table seeder as well, we could remove that, but we could tell the command line itself that we actually want to run specifically that class.
Adarsh:product-service adarshmaurya$ php artisan db:seed --class=ProductTableSeeder
Database seeding completed successfully.So we can add an option that’s called class to the db seed method. And then we’ll just tell it which class we want, which is ProductTableSeeder. So now when we run that guy, should have six.
Adarsh:product-service adarshmaurya$ php artisan db:seed
Database seeding completed successfully.
Adarsh:product-service adarshmaurya$ php artisan db:seed
Database seeding completed successfully.
Adarsh:product-service adarshmaurya$ php artisan db:seed
Database seeding completed successfully.So we already had the three main ones in there, we had beats, meats and greets one time, and then we ran the seed again and we said run only this particular class, and so if we decided that we wanted to run the main seeder over and over and over again, we would not see multiple records now, because it’s not included in the actual primary seeder. So the class method is good, it lets you kind of fine-tune what seeders you want to run. If you want to let them run all the time, you would just include them in that main DatabaseSeeder class, and then if you needed to be more sophisticated about when you want the data to show up, how you want it to be in there, whatever, you’d have to build some more logic inside of the seeder itself.
A quick point about that is that whenever you do the Artisan command to refresh the database and you tell it you want it to seed, it’s going to try and seed only the ones that are configured inside of the main DatabaseSeeder class, so right now that would not work for us because we don’t actually have our seeder built into the main one.
It’s a lot about seeding, but it’s a cool tool. I don’t, like I said, I only use it for development, if I’m building an API and I want thousands of records, so I can kind of check and see how it’s working, is it working well, that’s when I’ll use it. I very rarely use it to actually put production data in the database. But there are people that do that and that’s totally your call. Cool.