Laravel Eloquent для начинающих

Laravel Eloquent ORM — это способ взаимодействия с вашей базой данных. В этом уроке я покажу вам основы использования Laravel Eloquent, чтобы вы могли быстро начать использовать Eloquent.

Итак, что такое Eloquent ? Или что такое Eloquent модель ? Фактически это сводится к следующему: для каждой таблицы в вашей базе данных вы создаете модель Eloquent . Модель Eloquent — это просто класс PHP , который позволяет вам делать две вещи:

1) Взаимодействие с таблицей базы данных в целом . Например:

$users = User::all();

2) Управлять одной строкой в таблице . Например:

$user = User::first();

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

Итак, давайте просто начнем и покажем несколько примеров. В этой статье я буду использовать User модель Eloquent по умолчанию.

Начало работы с Laravel Eloquent

Чтобы начать работу с Laravel Eloquent , база данных должна иметь правильную структуру. Например, правильные таблицы и соответствующие им столбцы должны быть доступны. Вы определяете эту структуру при миграции базы данных .

После установки Laravel у вас по умолчанию есть три миграции: одна миграция для таблицы users , одна для password_resets и одна для failed_jobs. (Последнее предназначено для очередей в Laravel. Это расширенная функция, и в нее уже не нужно углубляться.)

Это миграция, которая создает таблицу пользователей, с несколькими комментариями с моей стороны:

<?php
 
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name'); 
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken(); 
            $table->timestamps();
        });
    }
 
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Теперь запустите одну из следующих команд, чтобы запустить миграцию:

php artisan migrate

Использование вашей первой модели Eloquent

Итак, что такое Eloquent? Каждая модель Eloquent представляет собой файл в каталоге App/Models . Итак, если вы заглянете в каталог App/Models , вы увидите там уже одну модель Eloquent по умолчанию: User.php

Как мы используем модели Eloquent?

use \App\Models\User;
 
public function save(Request $request): RedirectResponse
{
    $user = new User;
    $user->name = $request->input('name');
    $user->email = $request->input('email');
    $user->save();
    return redirect()->route('login');
}

Все эти операции можно выполнить с помощью одной из самых простых существующих моделей Eloquent:

<?php

namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
 
class User extends Authenticatable {}

Давайте посмотрим, как мы работаем с моделями Eloquent.

Создание и определение моделей Eloquent

Создадим новую модель Eloquent . И, как всегда, для этого есть команда artisan:

php artisan make:model Post

Это создает следующий файл в App/Models/Post.php :

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
 
class Post extends Model
{
    use HasFactory;
}

Если вы также хотите при создании модели автоматически создать миграцию , вы можете добавить  флаг -m в свою команду artisan:

php artisan make:model Post -m

Создание моделей Eloquent во вложенной папке

Вы также можете создавать модели Eloquent во вложенной папке . Для каждой папки добавьте его перед именем и добавьте косую черту. Так:

php artisan make:model Blog/Post

Имена таблиц и соглашение об именах Eloquent

Имя модели Eloquent обычно относится к имени таблицы. По умолчанию Laravel берет имя вашей таблицы и использует его во множественном числе.
  • Модель "Post" становится именем таблицы "posts"
  • Модель "UserPost" становится именем таблицы "user_posts"
  • Модель "EmailSubscriber" становится именем таблицы "email_subscribers"

Это чисто условность. Помните: имя модели Eloquent всегда в единственном числе , и если оно состоит из нескольких слов, слова разделяются заглавной буквой ( UserPost). Имя таблицы всегда во множественном числе и имеет вид «snake_cased» ( user_posts). Помните об этом соглашении, потому что оно может помочь вам позже.

Несколько примеров, в users таблице есть User модель. В categories таблице есть Catagory модель. В user_categories таблице есть UserCategory модель.

В любом случае, если имя вашей таблицы отличается от того, что предполагает соглашение, вы можете добавить в свой класс следующее:

protected $table = 'my_posts';

Основной ключ

По умолчанию Eloquent предполагает, что каждая таблица имеет первичное автоинкрементное целое число с именем id. Если ваша миграция содержит это (по умолчанию):

$table->id();

Тогда всё в порядке. Если нет, вы можете установить другой ключ в качестве первичного ключа :

protected $primaryKey = 'post_id';

Временные метки

По умолчанию Eloquent предполагает, что каждая таблица имеет столбец created_at и updated_at Если ваша миграция содержит это (по умолчанию):

$table->timestamps();

Если нет, сообщите Eloquent, что вы не используете временные метки:

public $timestamps = false;

Получение данных из модели Eloquent

Получение нескольких строк из Eloquent

Давайте теперь посмотрим, как мы используем Eloquent и получаем от него данные. Во-первых, давайте соберем все предметы . Есть два способа сделать это:

use App\Models\User;
 
$users = User::all();
$users = User::get(); // Just as valid, this means exactly the same
 
foreach ($users as $user) {
    echo $user->name;
}

Фильтруем результаты

Давайте немного отфильтруем результаты с  конструкцией where():
$admins = User::where('admin', true)->get();
 
foreach ($admins as $admin) {
   echo $admin->email;
}

В приведенном выше примере мы говорим, что столбец admin должен соответствовать значению true. Мы также можем добавить промежуточные операторы, добавив новый параметр:

// Пользователи, созданные более чем 7 дней назад
$admins = User::where('created_at', '<', now()->subDays(7))->get();

Получение одной строки из Eloquent

Теперь, когда мы увидели, как получить несколько записей и как их обработать, давайте посмотрим, как получить одну запись из базы данных .
Самый простой способ получить одну запись — найти ее по ее id. Вот пример:
$user = User::find(2); // получить пользователя с id=2

Еще один удобный способ использовать метод first(). Фактически это означает, что вы можете писать запросы, потенциально дающие несколько результатов, но вы получите только первый из них .

$user = User::where('admin', true)->first();

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

$oldest_comment = Comment::orderBy('created_at', 'asc')->first;
$newest_pos .= Post::latest()->first();

Методы firstOrFail() и findOrFail()

В приведенном выше примере вы видели, как мы можем использовать find() для поиска записи и first() для получения первой записи, соответствующей требованиям.

Но что происходит, когда запись не найдена ?

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

Чтобы решить эту проблему, у Eloquent есть два метода: findOrFail() и firstOrFail().

$user = User::findOrFail(2);
$user = User::where('admin', true)->firstOrFail();

В этом случае, когда Eloquent не нашел объект , он выдает исключение . Это звучит пугающе — я имею в виду, зачем вам вручную создавать исключения, если вы работаете только над их исправлением? Но это совсем не страшно.

Если выброшено исключение , то вам нужно его поймать . Звучит логично, правда? Если кто-то бросает мяч, кто-то должен его поймать. В противном случае он падает на землю, и игра («приложение») останавливается.

В этой ситуации, когда мы говорим о том, чтобы не найти записи Eloquent в базе данных, у вас есть два варианта:

  1. Пусть Laravel поймает и обработает исключение автоматически.

  2. Перехватите и обработайте исключение самостоятельно .

В случае findOrFail() и firstOrFail() Laravel, когда не находит модель, выдает исключение

Illuminate\Database\Eloquent\ModelNotFoundException

Если вы выберете вариант 1, вам не нужно ничего делать, кроме добавления OrFail() к вашим методам. Laravel автоматически поймает исключение и вернет страницу 404 Not found .

Это идеально подходит для ситуаций с такими URL-адресами, как /posts/edit/7, где 7 представляет сообщение id. Если сообщение не найдено, вполне нормально возвращать ошибку 404 Not found .

Но вы также можете справиться с этим самостоятельно. В этом случае поместите код, который потенциально возвращает ошибку, в try {} catch() {} блок :

try {
   $user = User::findOrFail(2);
   $user = User::where('admin', true)->firstOrFail();
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
   return redirect('/');
}

Обновление записей в Eloquent

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

Как создать новую запись Eloquent

Существует примерно два способа создания новых объектов Eloquent и их вставки (или нет) в базу данных. Для этого важно сначала понять разницу между созданием и изготовлением модели Eloquent .

Если вы создаете модель Eloquent , объект напрямую сохраняется в базе данных . Если вы создаете модель Eloquent , объект не сохраняется напрямую в базу данных , пока вы не вызовете его вручную ->save().

Первый способ создать объект Eloquent — просто создать новый экземпляр и отредактировать свойства.

$post = new Post;
$post->title = 'Заголовок статьи';
$post->content = 'Содержание статьи';
$post->author_id = auth()->user()->id; 

 
$post->save();

Есть и другой способ, который мне больше нравится. Приведенный выше код метода также можно было бы написать так, что, на мой взгляд, чище:

$post = Post::make([
   'title' => 'Заголовок статьи',
    'content' => 'Содержание статьи',
    'author_id' => auth()->user()->id,
]);

$post->save();
$post = Post::create([
   'title' => 'Заголовок статьи',
    'content' => 'Содержание статьи',
    'author_id' => auth()->user()->id,
]);

Делаем свойства заполняемыми в Eloquent

Как видите, разница между этими двумя способами заключается в разнице между:

  1. обновление каждого свойства вручную

  2. обновление нескольких свойств с помощью массива.

Я предпочитаю второй подход, потому что он позволяет писать меньше кода. Однако есть одна вещь, на которую следует обратить внимание. Рассмотрим следующий сценарий:

$post = Post::update($request->all());

В этом случае мы бы просто обновили все поля, которые приходят с данными запроса. Но что, если недобросовестный пользователь отправит такие поля, как id? И эти поля тоже будут обновляться?

Чтобы предотвратить этот сценарий, нам нужно установить определенные свойства, чтобы разрешить массовое назначение . Массовое назначение просто означает, что свойства обновляются из массива. Фактически вы добавляете свойство $guarded or $fillable в вашу модель Eloquent, с помощью которой вы говорите: эти и эти свойства можно изменить с помощью массива.

protected $fillable = [ 'title', 'content' ];

Или вы также можете разрешить все и защитить только несколько определенных свойств:

protected $guarded = [ 'author_id' ];

И если вы хотите разрешить массовое назначение для каждого поля, установите для $guarded пустой массив.

protected $guarded = [];

Laravel Eloquent отношения

Последняя часть Laravel Eloquent посвящена отношениям . Поскольку это очень важно для того, как вы работаете с данными и связываете их в Laravel, я посвящу дополнительную статью расширенным вариантам использования, но здесь я покажу вам основы, которые помогут вам быстро начать работу.

Во-первых, что такое отношения ? Отношения означают, что определенные записи принадлежат друг другу . Рассмотрим пользователя, у которого много сообщений. Каждый пост относится к категории. Каждый пост имеет много комментариев. Каждый комментарий принадлежит другому пользователю. У каждого пользователя есть определенная роль. Это все примеры отношений.

Что такое отношения на самом базовом уровне базы данных?

Основная идея отношений заключается в том, что у вас есть разные типы данных, поэтому они хранятся в разных таблицах, и вы соединяете эти два файла . Это делается путем добавления в таблицы таких столбцов, как user_id, post_id, и т. д. category_id

В приведенном выше примере postsтаблица имеет столбцы user_id и category_id.

  • В comments таблице есть столбцы user_id и post_id. (Каждый комментарий относится к одному посту и написан одним автором.)

  • В categories таблице нет лишних xxx_id столбцов, есть только собственный id столбец.

  • В roles таблице также нет лишних xxx_id столбцов.

  • В users таблице есть столбец role_id.

Создание столбцов отношений

Вы можете создать необходимые xxx_id столбцы в своей базе данных с помощью помощника foreignId() или foreignIdFor() в миграции базы данных.

$table->foreignId('user_id');
 
// или
 
$table->foreignIdFor(User::class);

Создание отношений

Есть несколько типов отношений. Наиболее распространенные из них:

  1. Отношения один к одному : Пользователь имеент одну роль.

  2. Отношения «один ко многим » : Пользователь имеет много сообщений. Даже если у пользователя есть только одно сообщение, у пользователя есть возможность иметь больше сообщений (когда он создает одно).

Создание отношений «один к одному» или «имеет один»

Создать отношение Eloquent так же просто, как добавить новый метод в нашу модель Eloquent. (Примечание: не миграция.)

Представьте, User что у него есть один, уникальный файл Membership. Это означает, что в memberships таблице есть user_id столбец.

Добавьте это в модель User :

public function membership(): HasOne
{
    return $this->hasOne(Membership::class);
}

А это для модели Membership :

public function user(): BelongsTo
{
    return $this->belongsTo(User::class);
}

Используйте это так:

$user = User::find(1);
 
$membership = $user->membership = 'Unique membership title';
$membership->save();
$user = Membership::find(1)->user;
 
$name = $user->name;

Создание отношения «один ко многим» или «имеет много»

Представьте распространенный пример, когда у пользователя много сообщений или много элементов. В этой ситуации добавьте xxx_id столбец в таблицу базы данных, в которой много элементов. В этой ситуации всегда есть один пользователь и несколько сообщений. Вы не можете легко добавить все в post_id таблицу пользователей, но вы можете добавить user_id в таблицу сообщений.

// User model
public function posts(): HasMany
{
    return $this->hasMany(Post::class);
}

А это для модели Post:

public function user(): BelongsTo
{
    return $this->belongsTo(User::class);
}

Заключение

Как мы видели, с Eloquent несложно начать работу , и он обеспечивает большую гибкость. Это повышает читабельность вашего кода и сэкономит вам много времени. Таким образом, я настоятельно рекомендую научиться использовать. Даже если вы изучаете только один новый метод каждый день, вы скоро станете профессионалом Eloquent.

На этом всё! Удачной вам разработки и адекватных клиентов

Коментарии

Коментарии отсутствуют, будьте первым(ой) кто напишет под этим постом!

Написать коментарий