Множественные отношения Laravel 10 для фабрики

У меня есть 3 таблицы: Категории, книги и авторы: Отношения:

  • Категории <> Книги (один ко многим)
  • Авторы <> Книги (один ко многим)

Я хотел бы вставить фиктивные данные, используя фабрику и сеялки. Поэтому сначала я создаю файлы миграции и модели для категорий и книг.

код в файле миграции book_table

public function up(): void
{
    Schema::create('books', function (Blueprint $table) {
        $table->id();
        $table->foreignId('category_id')->constrained()->cascadeOnDelete();
        $table->foreignId('author_id')->constrained()->cascadeOnDelete();
        $table->string('book_title' , 2500);
        $table->text('book_desc');
        $table->string('book_image');
        $table->timestamps();
    });

и в файле миграции категории_таблицы

public function up(): void
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id();
        $table->string('cat_name');
        $table->timestamps();
    });
}

и в DatabaseSeeder

\App\Models\Category::factory(3)
    ->create()
    ->each(function ($category) {
        \App\Models\Book::factory(4)
            ->create(['category_id' => $category->id]);
    });

Итак, я могу распределять данные между категориями <> книг.

затем я создаю файлы миграции и модели для автора

файл миграцииauthor_table

public function up(): void
{
    Schema::create('authors', function (Blueprint $table) {
        $table->id();
        $table->string('author_name');
        $table->timestamps();
    });
}

Но когда я попытался добавить фабрику в DatabaseSeeder для автора, вот так:

public function run(): void
{
    \App\Models\Category::factory(3)
        ->create()
        ->each(function ($category) {
            \App\Models\Book::factory(4)
                ->create(['category_id' => $category->id]);
        });

    \App\Models\Author::factory(5)
        ->create()
        ->each(function ($author) {
            \App\Models\Book::create(['author_id' => rand(1, 5)]);
        });
}

У меня 2 ошибки:

SQLSTATE[HY000]: Общая ошибка: 1005 Невозможно создать таблицу booky.books (ошибка: 150 «Ограничение внешнего ключа сформировано неправильно») (Соединение: mysql, SQL: изменить таблицу books добавить ограничение books_author_id_foreign ссылки на внешний ключ (author_id) authors (id) при каскадном удалении)

и

SQLSTATE[HY000]: общая ошибка: 1364 Поле «author_id» не имеет значения по умолчанию.

Я попытался вручную вставить поддельные данные в таблицу автора MySQL, но получил те же ошибки.

Любая помощь по этому вопросу будет принята с благодарностью

\App\Models\Author::factory(5)->create(); \App\Models\Category::factory(3)->create()->each(function ($category) { \App\Models\Book::factory(4)->create([ 'category_id' => $category->id, 'author_id' => \App\Models\Author::all()->random()->id // Assign a random author_id ]); }); ``` Это должно помочь вам
Hassaan Ali 17.03.2024 00:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
1
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, это две разные вещи, я их разберу.


SQLSTATE[HY000]: Общая ошибка: 1005 Невозможно создать таблицу booky.books (ошибка: 150 «Ограничение внешнего ключа сформировано неправильно»)

Проблема

Проблема, насколько я понимаю, заключается в том, что вы отредактировали исходную миграцию книг после создания таблицы авторов.

Другими словами, миграция ваших книг зависит от миграции авторов и категорий, которая выполнялась до нее.

Миграции выполняются по порядку, поэтому при запуске миграции происходит сбой в первой (книги), поскольку она пытается добавить ограничение внешнего ключа в таблицу, которая не существует (авторы).

Решение(я)

  • Измените порядок файлов миграции так, чтобы миграция «создать таблицу авторов» предшествовала «миграции создания книг», изменив имена файлов и затем запустив php artisan migrate:fresh
database/
    migrations/
        2024_03_16_000001_create_categories_table.php
        2024_03_16_000002_create_authors_table.php
        2024_03_16_000003_create_books_table.php
  • Альтернативно создайте четвертый файл миграции, чтобы добавить столбец books.author_id (и внешний ключ) в таблицу book.
return new class extends Migration
{
    public function up(): void
    {
        Schema::table('books', function (Blueprint $table) {
            $table->foreignId('author_id')
                ->constrained('authors')
                ->cascadeOnUpdate()
                ->cascadeOnDelete();
        });
    }

    public function down(): void
    {
        Schema::table('books', function (Blueprint $table) {
            $table->dropForeign(['author_id']);
            $table->dropColumn('author_id');
        });
    }
}

SQLSTATE[HY000]: общая ошибка: 1364 Поле «author_id» не имеет значения по умолчанию.

Проблема

Как следует из ошибки, проблема возникает из-за того, что вы вставляете строки в таблицу книг без указания идентификатора автора. Раньше это не было проблемой, потому что у вас не было столбцаauthor_id.

Решение(я)

Обновите свои фабрики или свой код, чтобы убедиться, что ни одна книга не сохраняется с нулевым значением в столбцеauthor_id.

use App\Models\Author;
use App\Models\Book;
use App\Models\Category;

// Create 4 Authors
$authors = Author::factory()->count(4)->create();
// Create 3 Categories
$categories = Category::factory()->count(3)->create();

// Make 5 Books (make does not save to the database)
$books = Book::factory()->count(5)->make()
    ->each(function (Book $book) use ($authors, $categories) {
        // fill relevant fields
        $book->author_id = $authors->random()->id;
        $book->category_id = $categories->random()->id;
        // now save to the database
        $book->save();
    });

В качестве альтернативы вы можете просто поручить эту задачу своей книжной фабрике.

class BookFactory extends Factory
{
    public function definition(): array
    {
        return [
            'author_id' => Author::factory(),
            'category_id' => Category::factory(),
            'book_title' => fake()->sentence,
            'book_desc' => fake()->paragraph,
            'book_image' => fake()->imageUrl,
        ];
    }
}

И тогда все, что вам нужно сделать, это вызвать Book::factory()->count(5)->create();, чтобы получить 5 книг, 5 категорий и 5 авторов.

Огромное спасибо не только за правильное решение, но и за четкое объяснение. Меня устраивает.

MohamedSalem 17.03.2024 14:02

Другие вопросы по теме