Laravel Eloquent ORM — это способ взаимодействия с вашей базой данных. В этом уроке я покажу вам основы использования Laravel Eloquent, чтобы вы могли быстро начать использовать Eloquent.
Итак, что такое Eloquent ? Или что такое Eloquent модель ? Фактически это сводится к следующему: для каждой таблицы в вашей базе данных вы создаете модель Eloquent . Модель Eloquent — это просто класс PHP , который позволяет вам делать две вещи:
1) Взаимодействие с таблицей базы данных в целом . Например:
$users = User::all();
2) Управлять одной строкой в таблице . Например:
$user = User::first();
Это дает вам исключительную гибкость и позволяет выполнять практически любые операции с базой данных.
Итак, давайте просто начнем и покажем несколько примеров. В этой статье я буду использовать User модель 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 представляет собой файл в каталоге 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 . И, как всегда, для этого есть команда 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 во вложенной папке . Для каждой папки добавьте его перед именем и добавьте косую черту. Так:
php artisan make:model Blog/Post
Это чисто условность. Помните: имя модели 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 и получаем от него данные. Во-первых, давайте соберем все предметы . Есть два способа сделать это:
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;
}
$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();
$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();
В приведенном выше примере вы видели, как мы можем использовать find() для поиска записи и first() для получения первой записи, соответствующей требованиям.
Но что происходит, когда запись не найдена ?
В таком случае вы получите null . Это может быть хорошо в некоторых простых (или очень сложных) ситуациях, так как вы можете просто проверить с помощью is_null(), но более вероятно, что вам нужно будет лучше и более профессионально справляться с ситуациями, когда запись не найдена .
Чтобы решить эту проблему, у Eloquent есть два метода: findOrFail() и firstOrFail().
$user = User::findOrFail(2);
$user = User::where('admin', true)->firstOrFail();
В этом случае, когда Eloquent не нашел объект , он выдает исключение . Это звучит пугающе — я имею в виду, зачем вам вручную создавать исключения, если вы работаете только над их исправлением? Но это совсем не страшно.
Если выброшено исключение , то вам нужно его поймать . Звучит логично, правда? Если кто-то бросает мяч, кто-то должен его поймать. В противном случае он падает на землю, и игра («приложение») останавливается.
В этой ситуации, когда мы говорим о том, чтобы не найти записи Eloquent в базе данных, у вас есть два варианта:
Пусть Laravel поймает и обработает исключение автоматически.
Перехватите и обработайте исключение самостоятельно .
В случае 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 , объект не сохраняется напрямую в базу данных , пока вы не вызовете его вручную ->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,
]);
Как видите, разница между этими двумя способами заключается в разнице между:
обновление каждого свойства вручную
обновление нескольких свойств с помощью массива.
Я предпочитаю второй подход, потому что он позволяет писать меньше кода. Однако есть одна вещь, на которую следует обратить внимание. Рассмотрим следующий сценарий:
$post = Post::update($request->all());
В этом случае мы бы просто обновили все поля, которые приходят с данными запроса. Но что, если недобросовестный пользователь отправит такие поля, как id? И эти поля тоже будут обновляться?
Чтобы предотвратить этот сценарий, нам нужно установить определенные свойства, чтобы разрешить массовое назначение . Массовое назначение просто означает, что свойства обновляются из массива. Фактически вы добавляете свойство $guarded or $fillable в вашу модель Eloquent, с помощью которой вы говорите: эти и эти свойства можно изменить с помощью массива.
protected $fillable = [ 'title', 'content' ];
Или вы также можете разрешить все и защитить только несколько определенных свойств:
protected $guarded = [ 'author_id' ];
И если вы хотите разрешить массовое назначение для каждого поля, установите для $guarded пустой массив.
protected $guarded = [];
Последняя часть 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);
Есть несколько типов отношений. Наиболее распространенные из них:
Отношения один к одному : Пользователь имеент одну роль.
Отношения «один ко многим » : Пользователь имеет много сообщений. Даже если у пользователя есть только одно сообщение, у пользователя есть возможность иметь больше сообщений (когда он создает одно).
Создать отношение 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.
На этом всё! Удачной вам разработки и адекватных клиентов
Коментарии отсутствуют, будьте первым(ой) кто напишет под этим постом!
Написать коментарий