Как использовать отношение One-to-Many в Laravel
One-to-Many— это наиболее распространённый тип отношений, используемый в Laravel Eloquent и ORM в целом.
Отношения One-to-Many
/Один-ко-Многим
— это наиболее распространённый тип отношений, используемый в Laravel Eloquent и ORM в целом. В этом руководстве мы рассмотрим реализацию этих отношений, создав пример приложения с двумя Laravel Моделями: Автор
и Книга
. Отношения, которые мы установим между этими Моделями, диктуют, что автор может иметь несколько книг, связанных с ним, в то время как книга может иметь только одного автора.
В Laravel Eloquent отношение One-to-Many
устанавливается с помощью метода hasMany
в одном классе и соответствующего метода belongsTo
в другом классе. Это создаст прямую связь между сущностями, обеспечивая лёгкий доступ к связанным данным.
Давайте сначала посмотрим на ERD ниже, где показаны две связанные таблицы, authors
и books
, которые мы свяжем через отношения Eloquent. Как вы можете видеть, книга имеет поле author_id
, которое указывает на id её владельца в таблице authors
.
Далее мы рассмотрим шаги по созданию необходимых миграций, определению отношений в моделях и выполнению общих операций над связанными данными. К концу этого руководства вы будете хорошо понимать, как использовать отношение One-to-Many
Шаг 1. Создание Миграций
Для начала давайте создадим миграции для таблиц authors
и books
. Выполните следующие команды в терминале:
php artisan make:migration create_authors_table --create=authors
php artisan make:migration create_books_table --create=books
Откройте файл миграции create_authors_table
и добавьте следующий код:
database/migrations/2023_06_26_191132_create_authors_table.php:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('authors', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('authors');
}
};
Аналогично откройте файл миграции create_books_table
и добавьте следующий код:
database/migrations/2023_06_26_191132_create_books_table.php:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->foreignIdFor(\App\Models\Author::class)->constrained();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('books');
}
};
В Laravel версии старше Laravel 8 вместо этого можно использовать следующее:
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description');
$table->unsignedBigInteger('author_id');
$table->foreign('author_id')->references('id')->on('authors');
$table->timestamps();
});
Для создания в базе данных таблиц authors
и books
выполните следующую команду artisan:
php artisan migrate
Шаг 2. Определение Моделей
Далее создадим модели для сущностей Author
и Book
. Выполните следующие команды:
php artisan make:model Author
php artisan make:model Book
Откройте модель Author
и определите связь One-to-Many
с моделью Book
app/Models/Author.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Author extends Model
{
public function books()
{
return $this->hasMany(Book::class);
}
}
Откройте модель Book
и определите обратную связь One-to-Many
:
app/Models/Book.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
public function author()
{
return $this->belongsTo(Author::class);
}
}
Шаг 3. Выполнение Запросов
Теперь, когда мы настроили миграции и модели, давайте выполним несколько запросов для получения данных и манипулирования ими, используя отношения One-to-Many
routes/web.php:
use App\Models\Author;
use App\Models\Book;
use Illuminate\Support\Facades\Route;
Route::get('/hasmany', function () {
// Создаём автора
$author = new Author();
$author->name = 'John Doe';
$author->email = 'john@example.com';
$author->save();
// Создаём книги и ассоциируем с автором
$book1 = new Book();
$book1->title = 'Book 1';
$book1->description = 'Description for Book 1';
$author->books()->save($book1);
$book2 = new Book();
$book2->title = 'Book 2';
$book2->description = 'Description for Book 2';
$author->books()->save($book2);
// Получение книг определённого автора (через hasMany)
$author = Author::first();
$books = $author->books;
dump($books);
// Получение автора книга (через belongsTo)
$book = Book::first();
$author = $book->author;
dump($author);
});
Заключение
В этом руководстве мы рассмотрели, как использовать отношение One-to-Many
в Laravel. Определив отношения, создав миграции, модели и выполнив запросы, мы успешно установили связь между двумя сущностями и эффективно извлекли связанные данные. Использование этих методов в ваших проектах поможет использовать возможности Eloquent и писать более лаконичный и читабельный код. Счастливого кодирования!