Магазин на Laravel 7, часть 1. Создание таблиц БД, заполнение начальными данными
28.09.2020
Теги: CLI • Laravel • MySQL • PHP • Web-разработка • БазаДанных • ИнтернетМагазин • КаталогТоваров • Миграции • Практика
Создание таблиц БД
Начнем с каталога товаров. Нам потребуются три таблицы в базе данных для хранения категорий, брендов и товаров. Подключаемся к серверу БД и создаем новую базу данных larashop
. После этого создаем три модели — Product
, Category
и Brand
— вместе с файлами миграции. Отредактируем файлы классов миграций, чтобы наши таблицы содержали все необходимые поля.
> php artisan make:model Category -m > php artisan make:model Brand -m > php artisan make:model Product -m
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateCategoriesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('categories', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('parent_id')->nullable(false)->default(0); $table->string('name', 100); $table->string('content', 200)->nullable(); $table->string('slug', 100)->unique(); $table->string('image', 50)->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('categories'); } }
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateBrandsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('brands', function (Blueprint $table) { $table->id(); $table->string('name', 100); $table->string('content', 200)->nullable(); $table->string('slug', 100)->unique(); $table->string('image', 50)->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('brands'); } }
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateProductsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('products', function (Blueprint $table) { $table->id(); $table->bigInteger('category_id')->unsigned()->nullable(); $table->bigInteger('brand_id')->unsigned()->nullable(); $table->string('name', 100); $table->text('content')->nullable(); $table->string('slug', 100)->unique(); $table->string('image', 50)->nullable(); $table->decimal('price', 10, 2, true)->default(0); $table->timestamps(); // внешний ключ, ссылается на поле id таблицы categories $table->foreign('category_id') ->references('id') ->on('categories') ->nullOnDelete(); // внешний ключ, ссылается на поле id таблицы brands $table->foreign('brand_id') ->references('id') ->on('brands') ->nullOnDelete(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('products'); } }
Перед тем, как создавать таблицы базы данных, надо задать параметры подключения к серверу БД в файле .env
:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=larashop DB_USERNAME=root DB_PASSWORD=qwerty
Теперь все готово к миграции, создаем таблицы базы данных с помощью команды:
> php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (0.03 seconds) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (0.03 seconds) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (0.02 seconds) Migrating: 2020_09_28_130327_create_categories_table Migrated: 2020_09_28_130327_create_categories_table (0.03 seconds) Migrating: 2020_09_28_130335_create_brands_table Migrated: 2020_09_28_130335_create_brands_table (0.03 seconds) Migrating: 2020_09_28_130346_create_products_table Migrated: 2020_09_28_130346_create_products_table (0.1 seconds)
-- -- Структура таблицы `users` -- CREATE TABLE `users` ( `id` bigint(20) UNSIGNED NOT NULL, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `email_verified_at` timestamp NULL DEFAULT NULL, `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -- Индексы таблицы `users` -- ALTER TABLE `users` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `users_email_unique` (`email`); -- -- AUTO_INCREMENT для таблицы `users` -- ALTER TABLE `users` MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT; COMMIT;
-- -- Структура таблицы `categories` -- CREATE TABLE `categories` ( `id` bigint(20) UNSIGNED NOT NULL, `parent_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0', `name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, `content` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `slug` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, `image` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -- Индексы таблицы `categories` -- ALTER TABLE `categories` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `categories_slug_unique` (`slug`); -- -- AUTO_INCREMENT для таблицы `categories` -- ALTER TABLE `categories` MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT; COMMIT;
-- -- Структура таблицы `brands` -- CREATE TABLE `brands` ( `id` bigint(20) UNSIGNED NOT NULL, `name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, `content` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `slug` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, `image` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -- Индексы таблицы `brands` -- ALTER TABLE `brands` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `brands_slug_unique` (`slug`); -- -- AUTO_INCREMENT для таблицы `brands` -- ALTER TABLE `brands` MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT; COMMIT;
-- -- Структура таблицы `products` -- CREATE TABLE `products` ( `id` bigint(20) UNSIGNED NOT NULL, `category_id` bigint(20) UNSIGNED DEFAULT NULL, `brand_id` bigint(20) UNSIGNED DEFAULT NULL, `name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, `content` text COLLATE utf8mb4_unicode_ci, `slug` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, `image` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `price` decimal(10,2) UNSIGNED NOT NULL DEFAULT '0.00', `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -- Индексы таблицы `products` -- ALTER TABLE `products` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `products_slug_unique` (`slug`), ADD KEY `products_category_id_foreign` (`category_id`), ADD KEY `products_brand_id_foreign` (`brand_id`); -- -- AUTO_INCREMENT для таблицы `products` -- ALTER TABLE `products` MODIFY `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT; -- -- Ограничения внешнего ключа таблицы `products` -- ALTER TABLE `products` ADD CONSTRAINT `products_brand_id_foreign` FOREIGN KEY (`brand_id`) REFERENCES `brands` (`id`) ON DELETE SET NULL, ADD CONSTRAINT `products_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL; COMMIT;
Заполнение таблиц БД
Laravel включает в себя механизм наполнения базы данных начальными данными (seeding) с помощью специальных классов. Все такие классы хранятся в директории database/seeds
. Для создания заготовок классов CategoryTableSeeder
, BrandTableSeeder
и ProductTableSeeder
используем команду:
> php artisan make:seeder CategoryTableSeeder > php artisan make:seeder BrandTableSeeder > php artisan make:seeder ProductTableSeeder
По умолчанию в Laravel уже определён класс DatabaseSeeder
. Из этого класса можно вызывать метод call()
для подключения других классов с данными, что позволит контролировать порядок их выполнения.
<?php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call(CategoryTableSeeder::class); $this->command->info('Таблица категорий загружена данными!'); $this->call(BrandTableSeeder::class); $this->command->info('Таблица брендов загружена данными!'); $this->call(ProductTableSeeder::class); $this->command->info('Таблица товаров загружена данными!'); } }
Файлы фабрик моделей хранятся в директории database/factories
, и там уже есть один готовый файл UserFactory.php
— это фабрика для модели User
. Чтобы создать фабрику для моделей Category
, Brand
и Product
— используем artisan-команду:
> php artisan make:factory CategoryFactory --model=Category > php artisan make:factory BrandFactory --model=Brand > php artisan make:factory ProductFactory --model=Product
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Category; use Illuminate\Support\Str; use Faker\Generator as Faker; $factory->define(Category::class, function (Faker $faker) { $name = $faker->realText(rand(30, 40)); return [ 'name' => $name, 'content' => $faker->realText(rand(150, 200)), 'slug' => Str::slug($name), ]; });
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Brand; use Illuminate\Support\Str; use Faker\Generator as Faker; $factory->define(Brand::class, function (Faker $faker) { $name = $faker->realText(rand(20, 30)); return [ 'name' => $name, 'content' => $faker->realText(rand(150, 200)), 'slug' => Str::slug($name), ]; });
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Product; use Illuminate\Support\Str; use Faker\Generator as Faker; $factory->define(Product::class, function (Faker $faker) { $name = $faker->realText(rand(40, 50)); return [ 'category_id' => rand(1, 4), 'brand_id' => rand(1, 4), 'name' => $name, 'content' => $faker->realText(rand(400, 500)), 'slug' => Str::slug($name), 'price' => rand(1000, 2000), ]; });
Осталось только отредактировать файлы классов CategoryTableSeeder
, BrandTableSeeder
и ProductTableSeeder
:
<?php use Illuminate\Database\Seeder; class CategoryTableSeeder extends Seeder { public function run() { // создать 4 категории factory(App\Category::class, 4)->create(); } }
<?php use Illuminate\Database\Seeder; class BrandTableSeeder extends Seeder { public function run() { // создать 4 бренда factory(App\Brand::class, 4)->create(); } }
<?php use Illuminate\Database\Seeder; class ProductTableSeeder extends Seeder { public function run() { // создать 12 товаров factory(App\Product::class, 12)->create(); } }
Заполняем таблицы базы данных начальными данными:
> php artisan migrate:fresh --seed
- Магазин на Laravel 7, часть 10. Форма оформления, сохранение заказа в базу данных
- Магазин на Laravel 7, часть 2. Создание контроллера и шаблонов, добавление маршрутов
- Магазин на Laravel 7, часть 25. Поиск по каталогу товаров, деплой проекта на хостинг TimeWeb
- Магазин на Laravel 7, часть 24. Фильтр товаров категории по цене, новинкам и лидерам продаж
- Магазин на Laravel 7, часть 23. Главная страница сайта, новинки, лидеры продаж и распродажа
- Магазин на Laravel 7, часть 22. Рефакторинг кода, работа над каталогом товаров и корзиной
- Магазин на Laravel 7, часть 21. Добавляем профили и используем их при оформлении заказа
Поиск: CLI • Laravel • MySQL • PHP • Web-разработка • База данных • Интернет магазин • Каталог товаров • Миграции • Практика