Laravel Database Management
Laravel, MariaDB, MySQL
This article focuses on Laravel 5.4 development in a Ubuntu 16.04 desktop environment. It is assumed that a suitable database has already been created.
Create a Database Table
The Laravel way involves creating and running a suitable “migration”. Migrations allow the app to create a new table or modify existing tables. Migrations are very powerful - amongst other things, they enable:
- Version control of the database
- Database modifications to be easily rolled-back
Create Migration
To create a migration:
php artisan make:migration create_users_tableThis creates a new file in the database/migrations directory. The filename is based on the option passed to php artisan make:migration and a timestamp - for example: database/migrations/2017_05_29_094813_create_users_table.php.
If the migration is to create a new table, you can specify the table name by passing the create option to make:migration command:
php artisan make:migration create_users_table --create=usersThis will stub out the migration file with the specified table. It’s probably a good idea to name the migration descriptively in the imperative case - for example “create_xx_table” or “adding_excerpt_to_posts_table”.
The following command sets up a migration that will create a database table called “stages”:
php artisan make:migration create_stages_table --table=stagesOnce the migration has been created, it needs to be run to actually create the database table:
php artisan migrateIn this case, the migration class will be in database/migrations/2017_05_20_112319_create_stages_table.php.
Before running the migration and creating the new table, you’ll probably want to add some columns. You can do this by editing the up() method on the newly created migration. For example, to add a simple title column:
<?php
public function up()
{
Schema::create('stages', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->timestamps();
});
}NOTE: you need to ensure that the additional table methods are added BEFORE the timestamps() method or they won’t be applied.
Run or Rollback Migration
To apply the changes to the database, you need to run the migration:
php artisan migrateTo rollback a migration:
php artisan migrate:rollbackSee: https://laravel.com/docs/5.4/migrations#generating-migrations
Rollback Problems
When attempting a rollback for the first time you may experience this error:
PHP Fatal error: Uncaught UnexpectedValueException:
The stream or file "/var/www/html/test-laravel/storage/logs/laravel.log"
could not be opened: failed to open stream:
Permission denied in /var/www/html/test-laravel/vendor
/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107This occurs because you’re running the rollback command as your current user. The storage directory will be owned by the server user (www-data in the case of Ubuntu), and will probably belong to your main user’s group (depending upon how you assigned permissions when you first installed the app).
The fix is simple - chmod the log file to give your user write permissions. The file will probably have -rw--r--r-- permissions, so change these to 664:
sudo chmod 664 /var/www/html/test-laravel/storage/logs/laravel.logSeeding a Table
Laravel 5.4 ships with the Faker Factory class included, which can be used to “seed” the database.
Create a seeder stub for the ‘stages’ table:
php artisan make:seeder StagesTableSeederThis stubs out a StagesTableSeeder class in database/seeds/StagesTableSeeder.php.
Example Seeder:
<?php
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
factory(App\User::class, 50)->create();
}
}Defining Model Factories
The method above uses the factory() helper function. This references a Model Factory that you can create in database/factories. You could add all factory logic in database/factories/ModelFactory.php - but it’s easier to keep code organised if you duplicate this file and add factory logic for your models within appropriately named files. For example, database/factories/PostFactory.php:
<?php
/*
|--------------------------------------------------------------------------
| Model Factory for Posts
|--------------------------------------------------------------------------
|
| Adds a random user_id to the dummy posts.
|
*/
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(App\Post::class, function (Faker\Generator $faker) {
$userID = App\User::inRandomOrder()->first()->id;
return [
'title' => $faker->sentence(),
'body' => $faker->text(60),
'excerpt' => $faker->text(30),
'user_id' => $userID,
];
});You can call the new seeder from the run() method in seeds/DatabaseSeeder.php:
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$this->call(UsersTableSeeder::class);
$this->call(PostsTableSeeder::class);
}
}This helps to keep seeder classes nice and neat.
Run the seeders:
php artisan db:seedRollback all database migrations and re-seed:
php artisan migrate:refresh --seedcomments powered by Disqus