Verification: a143cc29221c9be0

Php artisan migrate что это

Php artisan migrate что это

Введение

Это руководство позволит вам быстро освоить фреймворк Laravel. Оно содержит информацию о миграциях баз данных, Eloquent ORM, маршрутизации, проверке ввода, представлениях и Blade-шаблонах. Это отличная отправная точка для новичков в фреймворке Laravel и PHP-фреймворках в целом. Если вы уже использовали Laravel или другие PHP-фреймворки, вы можете ознакомиться с нашими более продвинутыми руководствами.

Чтобы рассмотреть основной набор функций Laravel, мы создадим простой список задач и будем придерживаться его (типичный пример списка «to-do»). Полный финальный вариант исходного кода для этого проекта доступен на GitHub.

Установка

Установка Laravel

Конечно, в первую очередь вам будет нужен свежий фреймворк Laravel. Чтобы запустить его, вы можете использовать виртуальную машину Homestead или локальную PHP-среду на ваш выбор. Как только ваше окружение будет готово, вы можете установить фреймворк Laravel, используя Composer:

shcomposer create-project laravel/laravel quickstart --prefer-dist

Установка проекта Quickstart (не обязательно)

Вы можете просто прочитать данное руководство. Однако, если вы хотите загрузить исходный код для этого руководства и выполнить его на локальной машине, то можете клонировать Git хранилище и установить зависимости:

shgit clone https://github.com/laravel/quickstart-basic quickstart
cd quickstart
composer install
php artisan migrate

Больше информации относительно создания локальной среды разработки Laravel вы сможете найти в документации по Homestead и по установке.

Подготовка базы данных

Миграции БД

Во-первых, давайте использовать миграцию для определения таблицы базы данных для хранения всех наших задач. Миграции БД в Laravel позволяют простым способом определить структуру таблицы базы данных и выполнять модификации с использованием простого и выразительного PHP кода. Вместо того чтобы вручную добавлять столбцы в свои локальные копии БД, ваши товарищи по команде могут просто запустить миграции, которые вы поместили в систему управления версиями.

Итак, давайте создадим таблицу БД, которая будет содержать все наши задачи. Для создания различных классов может быть использован интерфейс Artisan. Он избавит вас от ручной генерации кода при создании проектов Laravel. Поэтому давайте используем команду shmake:migration для создания миграции новой базы данных для нашей таблицы tasks:

shphp artisan make:migration create_tasks_table --create=tasks

Миграция будет помещена в каталог database/migrations вашего проекта. Как вы могли заметить, команда shmake:migration уже добавила автоинкремент ID и метки времени к файлу миграции. Давайте отредактируем этот файл и добавим дополнительный столбец string для имён наших задач:

PHP

use Illuminate\Database\Schema\Blueprint;
  use 
Illuminate\Database\Migrations\Migration;

  class 

CreateTasksTable extends Migration
  
{
    
/**
    * Запуск миграций
    *
    * @return void
    */
    
public function up()
    {
      
Schema::create('tasks', function (Blueprint $table) {
        
$table->increments('id');
        
$table->string('name');
        
$table->timestamps();
      });
    }
/**
    * Откатить миграции
    *
    * @return void
    */
    
public function down()
    {
      
Schema::drop('tasks');
    }
  }

Чтобы запустить нашу миграцию, мы будем использовать команду Artisan shmigrate. Если вы используете Homestead, вы должны выполнить эту команду в своей виртуальной машине, так как у вашей host-машины не будет прямого доступа к базе данных:

shphp artisan migrate

Эта команда создаст все наши таблицы БД. Если вы просматриваете таблицы БД, используя какой-либо клиент, вы должны заметить новую таблицу tasks, которая содержит столбцы, определённые в нашей миграции. Теперь мы готовы определить модель Eloquent ORM для наших задач!

Модели Eloquent

Eloquent — это стандартное ORM для Laravel (объектно-реляционное отображение). Eloquent делает безболезненным получение и хранение данных в вашей базе данных, используя чётко определённые «модели». Обычно, каждая Eloquent модель однозначно соответствует одной таблице базы данных.

Давайте определим модель Task, которая будет соответствовать только что созданной нами таблице tasks. Мы снова можем использовать команду Artisan, чтобы сгенерировать эту модель. В этом случае мы будем использовать команду shmake:model:

shphp artisan make:model Task

Модель будет помещена в каталог app вашего приложения. По умолчанию класс модели пуст. Нам не надо явно указывать, какой таблице соответствует Eloquent модель, потому что подразумевается, что имя таблицы – это имя модели во множественном числе (s на конце). В этом случае модель Task, как предполагается, соответствует таблице базы данных tasks. Вот на что должна быть похожа наша пустая модель:

PHP

namespace App;

  use 

Illuminate\Database\Eloquent\Model;

  class 

Task extends Model
  
{
    
//
  
}

Мы ещё познакомимся чуть ближе с моделями Eloquent, когда добавим маршруты к нашему приложению. Разумеется, вы можете заглянуть и в полную документацию по Eloquent для получения дополнительной информации.

Маршрутизация

Заглушки маршрутов

Теперь можно добавить несколько маршрутов в наше приложение. Маршруты используются для связи URL с контроллерами или анонимными функциями, которые должны быть выполнены, когда пользователь переходит на данную страницу. По умолчанию все маршруты Laravel определены в файле app/Http/routes.php, который автоматически добавляется в каждый новый проект.

Для нашего приложения нам будут нужны по крайней мере три маршрута: маршрут для вывода на экран списка всех наших задач, маршрут для добавления новых задач и маршрут для удаления существующих задач. Давайте напишем заглушки для всех этих маршрутов в файле app/Http/routes.php:

PHP

use App\Task;
  use 
Illuminate\Http\Request;/**
   * Вывести панель с задачами
   */
  
Route::get('/', function () {
    
//
  
});/**
   * Добавить новую задачу
   */
  
Route::post('/task', function (Request $request) {
    
//
  
});/**
   * Удалить задачу
   */
  
Route::delete('/task/{task}', function (Task $task) {
    
//
  
});

Если в вашей копии Laravel есть RouteServiceProvider, который уже содержит файл маршрутов по умолчанию в группе посредников web, то вам не надо вручную добавлять группу в ваш файл routes.php.

Вывод представления

Давайте заполним наш маршрут /. По этому маршруту мы хотим отрисовывать HTML-шаблон, который содержит форму добавления новой задачи, а также список всех текущих задач.

В Laravel все HTML-шаблоны хранятся в каталоге resources/views, и мы можем использовать вспомогательную функцию PHPview(), чтобы возвратить один из этих шаблонов по нашему маршруту:

PHP

Route::get('/', function () {
  return 
view('tasks');
});

Передача tasks в функцию PHPview() создаст экземпляр объекта View, который соответствует шаблону resources/views/tasks.blade.php.

Конечно, нам необходимо создать это представление, поэтому давайте сделаем это!

Создание макетов и представлений

Наше приложение содержит одно представление с формой добавления новых задач, а также список всех текущих задач. Чтобы помочь вам визуализировать представление, мы сделали скриншот законченного приложения со стандартными стилями Bootstrap CSS:

/packages/proger/habravel/uploads/374-basic-overview.png

Определяем макет

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

Как мы выяснили ранее, все представления Laravel хранятся в resources/views. Давайте определим представление нового макета в resources/views/layouts/app.blade.php. Расширение .blade.php даёт фреймворку команду использовать механизм шаблонной обработки Blade, чтобы отрисовать это представление. Конечно, в Laravel вы можете использовать и простые PHP-шаблоны. Однако Blade позволяет быстро написать простой и небольшой шаблон.

Наше представление app.blade.php должно выглядеть примерно так:

xml  


html lang="en">
  head>
    title>Laravel Quickstart - Basictitle>

    
  head>

  body>
    div class="container">
      nav class="navbar navbar-default">
        
      nav>
    div>

    @yield('content')
  body>
html>

Обратите внимание на строчку xml@yield('content') в макете. Это специальная Blade-директива для указания всем дочерним страницам, наследующим этот шаблон, где они могут внедрить своё содержимое. Давайте определим дочернее представление, которое будет использовать этот макет и выводить его основной контент.

Определяем дочернее представление

Теперь мы должны определить представление, которое содержит форму создания новой задачи, а также таблицу со списком всех существующих задач. Давайте определим это представление в resources/views/tasks.blade.php.

Мы пропустим небольшую часть Bootstrap CSS и сфокусируемся на важном. Помните, вы можете скачать весь исходный код этого приложения с ((https://github.com/laravel/quickstart-basic GitHub):

PHP

  

@extends(

'layouts.app')

@

section('content')

  

  

div class="panel-body">
    
    @include(
'common.errors')

    
    form action="{{ url('task') }}" method="POST" class="form-horizontal">
      {{ 
csrf_field() }}

      
      div class="form-group">
        label for="task" class="col-sm-3 control-label">Задачаlabel>

        

div class="col-sm-6">
          input type="text" name="name" id="task-name" class="form-control">
        
div>
      
div>

      
      div class="form-group">
        div class="col-sm-offset-3 col-sm-6">
          button type="submit" class="btn btn-default">
            class="fa fa-plus">iДобавить задачу
          
button>
        
div>
      
div>
    
form>
  
div>

  
@

endsection

Несколько разъясняющих замечаний

Прежде чем двигаться дальше, давайте немного поговорим об этом шаблоне. Во-первых, директива PHP@extends сообщает Blade, что мы используем макет, который мы определили в resources/views/layouts/app.blade.php. Все содержимое между PHP@section('content') и PHP@endsection будет добавлено вместо строчки директивы PHP@yield('content') в макете app.blade.php.

Директива PHP@include('common.errors') загрузит шаблон resources/views/common/errors.blade.php. Мы его ещё не определили, но скоро сделаем это!

Итак, мы определили основной макет и представление для нашего приложения. Помните, мы возвращаем это представление по маршруту /:

PHP

Route::get('/', function () {
  return 
view('tasks');
});

Теперь мы готовы добавить код в наш маршрут POST /task, чтобы обработать входящие данные из формы и добавить новую задачу в БД.

Добавление задач

Проверка ввода

Теперь, когда у нас есть форма на нашем представлении, мы должны добавить код к нашему маршруту POST /task в app/Http/routes.php, чтобы проверить входящие данные из формы и создать новую задачу. Во-первых, давайте проверим ввод.

Для этой формы мы создадим обязательное поле name и зададим, что оно должно содержать не более 255 символов. Если проверка не пройдёт, то мы перенаправим пользователя назад к URL /, а также возвратим ему в сессию его введённые данные с указанием на ошибки. Возврат введённых данных в сессию позволит нам сохранить их, даже если в них будут ошибки:

PHP

Route::post('/task', function (Request $request) {
  
$validator Validator::make($request->all(), [
    
'name' => 'required|max:255',
  ]);

  if (

$validator->fails()) {
    return 
redirect('/')
      ->
withInput()
      ->
withErrors($validator);
  }
// Создание задачи...
});

Переменная PHP$errors

Давайте сделаем перерыв на минутку, чтобы поговорить о строчке PHP->withErrors($validator) в нашем примере. Вызов PHP->withErrors($validator) подсветит в сессии ошибки данного экземпляра проверки ввода, и к ним можно будет обратиться через переменную PHP$errors в нашем представлении.

Помните, что мы использовали директиву PHP@include('common.errors') в нашем представлении, чтобы отобразить ошибки ввода формы. PHPcommon.errors позволяет нам легко показывать ошибки ввода в одинаковом формате на всех наших страницах. Давайте определим содержимое этого представления:

PHP

@if (

count($errors) > 0)
  
  div class="alert alert-danger">
    strong>УпсЧто-то пошло не так!strong>

    

br>br>

    

ul>
      @foreach (
$errors->all() as $error)
        li>{{ $error }}li>
      @endforeach
    
ul>
  
div>
@endif

Переменная PHP$errors доступна в любом представлении Laravel. Если не будет ошибок ввода, она просто будет пустым экземпляром PHPViewErrorBag.

Создание задачи

Теперь, когда обрабатывается ввод данных, давайте создадим новую задачу, продолжая заполнять наш маршрут. Как только новая задача была создана, мы перенаправим пользователя назад к URL /. Чтобы создать задачу, мы можем использовать метод PHPsave() после создания и установки свойств для новой модели Eloquent:

PHP

Route::post('/task', function (Request $request) {
  
$validator Validator::make($request->all(), [
    
'name' => 'required|max:255',
  ]);

  if (

$validator->fails()) {
    return 
redirect('/')
      ->
withInput()
      ->
withErrors($validator);
  }
$task = new Task;
  
$task->name $request->name;
  
$task->save();

  return 

redirect('/');
});

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

Отображение существующих задач

Во-первых, мы должны отредактировать наш маршрут /, чтобы передать все существующие задачи в представление. Функция PHPview() принимает массив данных вторым параметром, который будет доступным для представления. Каждый ключ массива станет переменной в представлении:

PHP

Route::get('/', function () {
  
$tasks Task::orderBy('created_at''asc')->get();

  return 

view('tasks', [
    
'tasks' => $tasks
  
]);
});

Когда данные переданы, мы можем обращаться к задачам в нашем представлении tasks.blade.php и выводить их на экран таблицей. Blade-конструкция PHP@foreach позволяет нам кратко писать циклы, которые компилируются в молниеносный простой PHP-код:

PHP

@extends('layouts.app')

@

section('content')
  

  
  @if (

count($tasks) > 0)
    div class="panel panel-default">
      div class="panel-heading">
        
Текущая задача
      
div>

      

div class="panel-body">
        table class="table table-striped task-table">

          
          thead>
            th>Taskth>
            th> th>
          
thead>

          
          tbody>
            @foreach (
$tasks as $task)
              tr>
                
                td class="table-text">
                  div>{{ $task->name }}div>
                
td>

                

td>
                  
                
td>
              
tr>
            @endforeach
          
tbody>
        
table>
      
div>
    
div>
   @endif
@
endsection

Наше приложение почти готово. Но у нас нет способа удалять наши существующие задачи, когда они завершены. Давайте добавим и это!

Введение

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

Фасад Schema обеспечивает независимую от базы данных поддержку для создания и управления таблицами во всех поддерживаемых Laravel системах баз данных. В обычной ситуации, этот фасад используется для создания и изменения таблиц / столбцов базы данных во время миграции.

Генерация миграций

Чтобы сгенерировать новую миграцию базы данных, используйте команду make:migration Artisan. Эта команда поместит новый класс миграции в каталог database/migrations вашего приложения. Каждое имя файла миграции содержит временную метку, которая позволяет Laravel определять порядок применения миграций:

php artisan make:migration create_flights_table

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

Если вы хотите указать собственный путь для сгенерированной миграции, вы можете использовать параметр --path при выполнении команды make:migration. Указанный путь должен быть относительно базового пути вашего приложения.

Заготовки миграции можно настроить с помощью публикации заготовок.

Сжатие миграций

По мере создания приложения вы можете со временем накапливать все больше и больше миграций. Это может привести к тому, что ваш каталог database/migrations станет раздутым из-за потенциально сотен миграций. Если хотите, то можете «сжать» свои миграции в один файл SQL. Для начала выполните команду schema:dump:

php artisan schema:dump


php artisan schema:dump --prune

Когда вы выполните эту команду, Laravel запишет файл «схемы» в каталог database/schema вашего приложения. Теперь, когда вы попытаетесь перенести свою базу данных, Laravel сначала выполнит SQL-операторы файла схемы, при условии, что никакие другие миграции не выполнялись. После выполнения команд файла схемы, Laravel выполнит все оставшиеся миграции, которые не были включены в дамп схемы БД.

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

Сжатие миграции доступно только для баз данных MySQL, PostgreSQL и SQLite и использует клиент командной строки базы данных. Дампы схемы не могут быть восстановлены в базах данных SQLite, хранимых в памяти.

Структура миграций

Класс миграции содержит два метода: up и down. Метод up используется для добавления новых таблиц, столбцов или индексов в вашу базу данных, тогда как метод down должен отменять операции, выполняемые методом up.

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

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateFlightsTable extends Migration
{
    
    public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    
    public function down()
    {
        Schema::drop('flights');
    }
}

Анонимные миграции

Как вы могли заметить в примере выше, Laravel автоматически присваивает имя класса всем миграциям, которые вы создаете с помощью команды make:migration. Однако, если вы хотите, вы можете вернуть анонимный класс из вашего файла миграции. Это может быть полезно, если в вашем приложении накопилось много миграций и некоторые имеют одинаковые названия.

use Illuminate\Database\Migrations\Migration;

return new class extends Migration
{
    
};

Указание соединения миграции

Если ваша миграция будет использовать соединение с базой данных, отличное от соединения с базой данных по умолчанию для вашего приложения, то необходимо установить свойство $connection миграции:


protected $connection = 'pgsql';


public function up()
{
    
}

Запуск миграций

Чтобы запустить все незавершенные миграции, выполните команду migrate Artisan:

php artisan migrate

Если вы хотите узнать, какие миграции уже выполнены, то вы можете использовать команду migrate:status Artisan:

php artisan migrate:status

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

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

php artisan migrate --force

Откат миграций

Чтобы откатить последнюю операцию миграции, вы можете использовать команду rollback Artisan. Эта команда откатывает последний «пакет» миграций, который может включать несколько файлов миграции:

php artisan migrate:rollback

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

php artisan migrate:rollback --step=5

Команда migrate:reset откатит все миграции вашего приложения:

php artisan migrate:reset

Откат и миграция с помощью одной команды

Команда migrate:refresh откатит все ваши миграции, а затем выполнит команду migrate. Эта команда эффективно воссоздает всю вашу базу данных:

php artisan migrate:refresh


php artisan migrate:refresh --seed

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

php artisan migrate:refresh --step=5

Удаление всех таблиц с последующей миграцией

Команда migrate:fresh удалит все таблицы из базы данных, а затем выполнит команду migrate:

php artisan migrate:fresh

php artisan migrate:fresh --seed
Команда migrate:fresh удалит все таблицы базы данных независимо от их префикса. Эту команду следует использовать с осторожностью при разработке в базе данных, которая используется совместно с другими приложениями.

Таблицы

Создание таблиц

Чтобы создать новую таблицу базы данных, используйте метод create фасада Schema. Метод create принимает два аргумента: первый – это имя таблицы, а второй – замыкание, которое получает объект Blueprint, используемый для определения новой таблицы:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email');
    $table->timestamps();
});

При создании таблицы вы можете использовать любой из методов столбцов построителя схемы для определения столбцов таблицы.

Проверка наличия таблицы / столбца

Вы можете проверить наличие таблицы или столбца с помощью методов hasTable и hasColumn, соответственно:

if (Schema::hasTable('users')) {
    
}

if (Schema::hasColumn('users', 'email')) {
    
}

Соединение с базой данных и параметры таблицы

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

Schema::connection('sqlite')->create('users', function (Blueprint $table) {
    $table->id();
});

Кроме того, некоторые другие свойства и методы могут использоваться для определения других аспектов создания таблицы. Свойство engine используется для указания механизма хранения таблицы при использовании MySQL:

Schema::create('users', function (Blueprint $table) {
    $table->engine = 'InnoDB';

    
});

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

Schema::create('users', function (Blueprint $table) {
    $table->charset = 'utf8mb4';
    $table->collation = 'utf8mb4_unicode_ci';

    
});

Метод temporary используется, чтобы указать, что таблица должна быть «временной». Временные таблицы видны только текущему сеансу соединения базы данных и автоматически удаляются при закрытии соединения:

Schema::create('calculations', function (Blueprint $table) {
    $table->temporary();

    
});

Обновление таблиц

Метод table фасада Schema используется для обновления существующих таблиц. Подобно методу create, метод table принимает два аргумента: имя таблицы и замыкание, которое получает экземпляр Blueprint, используемый для добавления столбцов или индексов в таблицу:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes');
});

Переименование / удаление таблиц

Чтобы переименовать существующую таблицу базы данных, используйте метод rename:

use Illuminate\Support\Facades\Schema;

Schema::rename($from, $to);

Чтобы удалить существующую таблицу, вы можете использовать методы drop или dropIfExists:

Schema::drop('users');

Schema::dropIfExists('users');

Переименование таблиц с внешними ключами

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

Столбцы

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

Метод table фасада Schema используется для обновления существующих таблиц. Как и метод create, метод table принимает два аргумента: имя таблицы и замыкание, которое получает экземпляр Illuminate\Database\Schema\Blueprint, используемый для добавления столбцов в таблицу:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes');
});

Доступные типы столбцов

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

  • bigIncrements
  • bigInteger
  • binary
  • boolean
  • char
  • dateTimeTz
  • dateTime
  • date
  • decimal
  • double
  • enum
  • float
  • foreignId
  • geometryCollection
  • geometry
  • id
  • increments
  • integer
  • ipAddress
  • json
  • jsonb
  • lineString
  • longText
  • macAddress
  • mediumIncrements
  • mediumInteger
  • mediumText
  • morphs
  • multiLineString
  • multiPoint
  • multiPolygon
  • nullableMorphs
  • nullableTimestamps
  • nullableUuidMorphs
  • point
  • polygon
  • rememberToken
  • set
  • smallIncrements
  • smallInteger
  • softDeletesTz
  • softDeletes
  • string
  • text
  • timeTz
  • time
  • timestampTz
  • timestamp
  • timestampsTz
  • timestamps
  • tinyIncrements
  • tinyInteger
  • tinyText
  • unsignedBigInteger
  • unsignedDecimal
  • unsignedInteger
  • unsignedMediumInteger
  • unsignedSmallInteger
  • unsignedTinyInteger
  • uuidMorphs
  • uuid
  • year

bigIncrements()

Метод bigIncrements создает эквивалент автоинкрементного столбца UNSIGNED BIGINT (первичный ключ):

$table->bigIncrements('id');

bigInteger()

Метод bigInteger создает эквивалент столбца BIGINT:

$table->bigInteger('votes');

binary()

Метод binary создает эквивалент столбца BLOB:

$table->binary('photo');

boolean()

Метод boolean создает эквивалент столбца BOOLEAN:

$table->boolean('confirmed');

char()

Метод char создает эквивалент столбца CHAR указанной длины:

$table->char('name', 100);

dateTimeTz()

Метод dateTimeTz создает эквивалент столбца DATETIME (с часовым поясом) с необязательной точностью (общее количество цифр):

$table->dateTimeTz('created_at', $precision = 0);

dateTime()

Метод dateTime создает эквивалент столбца DATETIME с необязательной точностью (общее количество цифр):

$table->dateTime('created_at', $precision = 0);

date()

Метод date создает эквивалент столбца DATE:

$table->date('created_at');

decimal()

Метод decimal создает эквивалент столбца DECIMAL с точностью (общее количество цифр) и масштабом (десятичные цифры):

$table->decimal('amount', $precision = 8, $scale = 2);

double()

Метод double создает эквивалент столбца DOUBLE с точностью (общее количество цифр) и масштабом (десятичные цифры):

$table->double('amount', 8, 2);

enum()

Метод enum создает эквивалент столбца ENUM с указанием допустимых значений:

$table->enum('difficulty', ['easy', 'hard']);

float()

Метод float создает эквивалент столбца FLOAT с точностью (общее количество цифр) и масштабом (десятичные цифры):

$table->float('amount', 8, 2);

foreignId()

Метод foreignId является псевдонимом метода unsignedBigInteger:

$table->foreignId('user_id');

geometryCollection()

Метод geometryCollection создает эквивалент столбца GEOMETRYCOLLECTION:

$table->geometryCollection('positions');

geometry()

Метод geometry создает эквивалент столбца GEOMETRY:

$table->geometry('positions');

id()

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

$table->id();

increments()

Метод increments создает эквивалент автоинкрементного столбца UNSIGNED INTEGER в качестве первичного ключа:

$table->increments('id');

integer()

Метод integer создает эквивалент столбца INTEGER:

$table->integer('votes');

ipAddress()

Метод ipAddress создает эквивалент столбца VARCHAR:

$table->ipAddress('visitor');

json()

Метод json создает эквивалент столбца JSON:

$table->json('options');

jsonb()

Метод jsonb создает эквивалент столбца JSONB:

$table->jsonb('options');

lineString()

Метод lineString создает эквивалент столбца LINESTRING:

$table->lineString('positions');

longText()

Метод longText создает эквивалент столбца LONGTEXT:

$table->longText('description');

macAddress()

Метод macAddress создает столбец, предназначенный для хранения MAC-адреса. Некоторые системы баз данных, такие как PostgreSQL, имеют специальный тип столбца для этого типа данных. Другие системы баз данных будут использовать столбец строкового эквивалента:

$table->macAddress('device');

mediumIncrements()

Метод mediumIncrements создает эквивалент автоинкрементного столбца UNSIGNED MEDIUMINT в качестве первичного ключа:

$table->mediumIncrements('id');

mediumInteger()

Метод mediumInteger создает эквивалент столбца MEDIUMINT:

$table->mediumInteger('votes');

mediumText()

Метод mediumText создает эквивалент столбца MEDIUMTEXT:

$table->mediumText('description');

morphs()

Метод morphs – это удобный метод, который добавляет эквивалент столбца UNSIGNED BIGINT ({column}_id) и эквивалент столбца VARCHAR ({column}_type).

Этот метод предназначен для использования при определении столбцов, необходимых для полиморфного отношения Eloquent. В следующем примере будут созданы столбцы taggable_id и taggable_type:

$table->morphs('taggable');

multiLineString()

Метод multiLineString создает эквивалент столбца MULTILINESTRING:

$table->multiLineString('positions');

multiPoint()

Метод multiPoint создает эквивалент столбца MULTIPOINT:

$table->multiPoint('positions');

multiPolygon()

Метод multiPolygon создает эквивалент столбца MULTIPOLYGON:

$table->multiPolygon('positions');

nullableTimestamps()

Метод аналогичен методу timestamps; тем не менее, создаваемый столбец будет иметь значение NULL:

$table->nullableTimestamps(0);

nullableMorphs()

Метод аналогичен методу morphs; тем не менее, создаваемый столбец будет иметь значение NULL:

$table->nullableMorphs('taggable');

nullableUuidMorphs()

Метод аналогичен методу uuidMorphs; тем не менее, создаваемый столбец будет иметь значение NULL:

$table->nullableUuidMorphs('taggable');

point()

Метод point создает эквивалент столбца POINT:

$table->point('position');

polygon()

Метод polygon создает эквивалент столбца POLYGON:

$table->polygon('position');

rememberToken()

Метод rememberToken создает NULL-эквивалент столбца VARCHAR(100), предназначенный для хранения текущего токена аутентификации:

$table->rememberToken();

set()

Метод set создает эквивалент столбца SET с заданным списком допустимых значений:

$table->set('flavors', ['strawberry', 'vanilla']);

smallIncrements()

Метод smallIncrements создает эквивалент автоинкрементного столбца UNSIGNED SMALLINT в качестве первичного ключа:

$table->smallIncrements('id');

smallInteger()

Метод smallInteger создает эквивалент столбца SMALLINT:

$table->smallInteger('votes');

softDeletesTz()

Метод softDeletesTz добавляет NULL-эквивалент столбца TIMESTAMP (с часовым поясом) с необязательной точностью (общее количество цифр). Этот столбец предназначен для хранения временной метки deleted_at, необходимой для функции «программного удаления» Eloquent:

$table->softDeletesTz($column = 'deleted_at', $precision = 0);

softDeletes()

Метод softDeletes добавляет NULL-эквивалент столбца TIMESTAMP с необязательной точностью (общее количество цифр). Этот столбец предназначен для хранения временной метки deleted_at, необходимой для функции «программного удаления» Eloquent:

$table->softDeletes($column = 'deleted_at', $precision = 0);

string()

Метод string создает эквивалент столбца VARCHAR указанной длины:

$table->string('name', 100);

text()

Метод text создает эквивалент столбца TEXT:

$table->text('description');

timeTz()

Метод timeTz создает эквивалент столбца TIME (с часовым поясом) с необязательной точностью (общее количество цифр):

$table->timeTz('sunrise', $precision = 0);

time()

Метод time создает эквивалент столбца TIME с необязательной точностью (общее количество цифр):

$table->time('sunrise', $precision = 0);

timestampTz()

Метод timestampTz создает эквивалент столбца TIMESTAMP (с часовым поясом) с необязательной точностью (общее количество цифр):

$table->timestampTz('added_at', $precision = 0);

timestamp()

Метод timestamp создает эквивалент столбца TIMESTAMP с необязательной точностью (общее количество цифр):

$table->timestamp('added_at', $precision = 0);

timestampsTz()

Метод timestampsTz создает столбцы created_at и updated_at, эквивалентные TIMESTAMP (с часовым поясом) с необязательной точностью (общее количество цифр):

$table->timestampsTz($precision = 0);

timestamps()

Метод timestamps method creates created_at and updated_at TIMESTAMP с необязательной точностью (общее количество цифр):

$table->timestamps($precision = 0);

tinyIncrements()

Метод tinyIncrements создает эквивалент автоинкрементного столбца UNSIGNED TINYINT в качестве первичного ключа:

$table->tinyIncrements('id');

tinyInteger()

Метод tinyInteger создает эквивалент столбца TINYINT:

$table->tinyInteger('votes');

tinyText()

Метод tinyText создаёт эквивалент столбца TINYTEXT:

$table->tinyText('notes');    

unsignedBigInteger()

Метод unsignedBigInteger создает эквивалент столбца UNSIGNED BIGINT:

$table->unsignedBigInteger('votes');

unsignedDecimal()

Метод unsignedDecimal создает эквивалент столбца UNSIGNED DECIMAL с необязательной точностью (общее количество цифр) и масштабом (десятичные цифры):

$table->unsignedDecimal('amount', $precision = 8, $scale = 2);

unsignedInteger()

Метод unsignedInteger создает эквивалент столбца UNSIGNED INTEGER:

$table->unsignedInteger('votes');

unsignedMediumInteger()

Метод unsignedMediumInteger создает эквивалент столбца UNSIGNED MEDIUMINT:

$table->unsignedMediumInteger('votes');

unsignedSmallInteger()

Метод unsignedSmallInteger создает эквивалент столбца UNSIGNED SMALLINT:

$table->unsignedSmallInteger('votes');

unsignedTinyInteger()

Метод unsignedTinyInteger создает эквивалент столбца UNSIGNED TINYINT:

$table->unsignedTinyInteger('votes');

uuidMorphs()

Метод uuidMorphs – это удобный метод, который добавляет эквивалент столбца CHAR(36) ({column}_id) и эквивалент столбца VARCHAR ({column}_type).

Этот метод предназначен для использования при определении столбцов, необходимых для полиморфного отношения Eloquent, использующего идентификаторы UUID. В следующем примере будут созданы столбцы taggable_id и taggable_type:

$table->uuidMorphs('taggable');

uuid()

Метод uuid создает эквивалент столбца UUID:

$table->uuid('id');

year()

Метод year создает эквивалент столбца YEAR:

$table->year('birth_year');

Модификаторы столбца

В дополнение к типам столбцов, перечисленным выше, есть несколько «модификаторов» столбцов, которые вы можете использовать при добавлении столбца в таблицу базы данных. Например, чтобы сделать столбец «допускающим значение NULL», вы можете использовать метод nullable:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->string('email')->nullable();
});

В следующей таблице представлены все доступные модификаторы столбцов. В этот список не входят модификаторы индексов:

Модификатор Описание
->after('column') Поместить столбец «после» другого столбца (MySQL).
->autoIncrement() Установить столбцы INTEGER как автоинкрементные (первичный ключ).
->charset('utf8mb4') Указать набор символов для столбца (MySQL).
->collation('utf8mb4_unicode_ci') Указать параметры сравнения для столбца (MySQL/PostgreSQL/SQL Server).
->comment('my comment') Добавить комментарий к столбцу (MySQL/PostgreSQL).
->default($value) Указать значение «по умолчанию» для столбца.
->first() Поместить столбец «первым» в таблице (MySQL).
->from($integer) Установить начальное значение автоинкрементного поля (MySQL / PostgreSQL).
->nullable($value = true) Позволить (по умолчанию) значения NULL для вставки в столбец.
->storedAs($expression) Создать сохраненный генерируемый столбец (MySQL).
->unsigned() Установить столбцы INTEGER как UNSIGNED (MySQL).
->useCurrent() Установить столбцы TIMESTAMP для использования CURRENT_TIMESTAMP в качестве значения по умолчанию.
->useCurrentOnUpdate() Установить столбцы TIMESTAMP для использования CURRENT_TIMESTAMP при обновлении записи.
->virtualAs($expression) Создать виртуальный генерируемый столбец (MySQL).
->generatedAs($expression) Создать столбец идентификаторов с указанными параметрами последовательности (PostgreSQL).
->always() Определить приоритет значений последовательности над вводом для столбца идентификаторов (PostgreSQL).

Выражения для значений по умолчанию

Модификатор default принимает значение или экземпляр Illuminate\Database\Query\Expression. Использование экземпляра Expression не позволит Laravel заключить значение в кавычки и позволит вам использовать функции, специфичные для базы данных. Одна из ситуаций, когда это особенно полезно, когда вам нужно назначить значения по умолчанию для столбцов JSON:

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Migrations\Migration;

class CreateFlightsTable extends Migration
{
    
    public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->json('movies')->default(new Expression('(JSON_ARRAY())'));
            $table->timestamps();
        });
    }
}
Поддержка выражений по умолчанию зависит от вашего драйвера базы данных, версии базы данных и типа поля. См. документацию к вашей базе данных.

Порядок столбцов

Метод after добавляет набор столбцов после указанного существующего столбца в схеме базы данных MySQL:

$table->after('password', function ($table) {
    $table->string('address_line1');
    $table->string('address_line2');
    $table->string('city');
});

Изменение столбцов

Необходимые компоненты

Перед изменением столбца вы должны установить пакет doctrine/dbal с помощью менеджера пакетов Composer. Библиотека Doctrine DBAL используется для определения текущего состояния столбца и для создания запросов SQL, необходимых для внесения запрошенных изменений в столбец:

composer require doctrine/dbal

Если вы планируете изменять столбцы, созданные с помощью метода timestamp, вы также должны добавить следующую конфигурацию в файл config/database.php вашего приложения:

use Illuminate\Database\DBAL\TimestampType;

'dbal' => [
    'types' => [
        'timestamp' => TimestampType::class,
    ],
],
Если ваше приложение использует Microsoft SQL Server, то убедитесь, что вы установили doctrine/dbal:^3.0.

Обновление атрибутов столбца

Метод change позволяет вам изменять тип и атрибуты существующих столбцов. Например, вы можете увеличить размер string столбца. Чтобы увидеть метод change в действии, давайте увеличим размер столбца name до 50. Для этого мы просто определяем новое состояние столбца и затем вызываем метод change:

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change();
});

Мы также можем изменить столбец, чтобы он допускал значение NULL:

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->nullable()->change();
});
Только следующие типы столбцов могут быть изменены: bigInteger, binary, boolean, date, dateTime, dateTimeTz, decimal, integer, json, longText, mediumText, smallInteger, string, text, time, unsignedBigInteger, unsignedInteger, unsignedSmallInteger, и uuid. Чтобы изменить типа столбца timestamp у вас должна быть установлена библиотека Doctrine DBAL.

Переименование столбцов

Чтобы переименовать столбец, вы можете использовать метод renameColumn построителя схемы Blueprint. Перед переименованием столбца убедитесь, что вы установили библиотеку doctrine/dbal через менеджер пакетов Composer:

Schema::table('users', function (Blueprint $table) {
    $table->renameColumn('from', 'to');
});
Переименование enum столбца в настоящее время не поддерживается.

Удаление столбцов

Чтобы удалить столбец, вы можете использовать метод dropColumn построителя схемы Blueprint. Если ваше приложение использует базу данных SQLite, то вы должны установить библиотеку doctrine/dbal через менеджер пакетов Composer, прежде чем использовать метод dropColumn:

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn('votes');
});

Вы можете удалить несколько столбцов из таблицы, передав массив имен столбцов методу dropColumn:

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn(['votes', 'avatar', 'location']);
});
Удаление или изменение нескольких столбцов в рамках одной миграции при использовании базы данных SQLite не поддерживается.

Доступные псевдонимы команд

Laravel содержит несколько удобных методов, связанных с удалением общих типов столбцов. Каждый из этих методов описан в таблице ниже:

Команда Описание
$table->dropMorphs('morphable'); Удалить столбцы morphable_id и morphable_type.
$table->dropRememberToken(); Удалить столбец remember_token.
$table->dropSoftDeletes(); Удалить столбец deleted_at.
$table->dropSoftDeletesTz(); Псевдоним dropSoftDeletes().
$table->dropTimestamps(); Удалить столбцы created_at и updated_at.
$table->dropTimestampsTz(); Псевдоним dropTimestamps().

Disclaimer

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

Описание проблемы

Есть у нас ветка драфт, что бы пушить в драфт не надо делать МР, эта ветка нужна для того что бы программист мог по быстрому показать свои наработки бизнес аналитику, что бы фронт-энд мог интегрироваться с изменениями на бэк-энде. Драфт регулярно ресетиться.

То есть ты что то сделал с функционалом, решил показать другим разработчикам - выкатываешь всё на драфт, на БД драфта раскатывается твоя миграция, ты показал, понял что был не прав и переделываешь миграцию, в это время кто то ресетит драфт вместе с твоей миграцией, и что мы имеем ? мы имеем миграцию которая были применена и которую ни кто не откатил, как думаете получиться ещё раз её применить ?

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

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

Правило первое: "накатывать можно бесконечно"

Правило первое, пишем миграцию так что бы её можно было бесконечное количество раз накатывать на саму себя. То есть накатываем миграцию, удаляем запись этой миграции в таблице migrations, и если мы ещё раз накатим эту же миграцию, то не должно быть эксепшена, миграция не должна вызвать сбой.

Миграцию можно как бесконечное количество раз накатить на саму себя, так и откатить с самой себя.

Для работы миграциями по штучно я использую такое команды:

# накатить конкретную миграцию
php artisan migrate --path="services/best-team-servise/database/migrations/2021_02_04_240000_alter_data_model_table_add_unique_index.php" --pretend
# ключ --pretend позволит нам посмотреть SQL до того как будет применена миграция, иногда полезно

# откатить ровно одну миграцию
php artisan migrate:rollback --step=1
# можно откатить и десять, при случае раберётесь

После того как миграция применена, можно сгенерировать описание модели

php artisan ide-helper:models "Project\Models\DataModel"

и сделать посев данных:

php artisan db:seed --class=DataModelSeeder

Как сделать так что бы миграцию можно было бесконечно применять ? в методах up() и down() миграции, мы должны делать проверку того, что действие со схемой БД можно выполнить.

Если мы добавляем колонку, то проверяем что колонка не существует, если мы дропаем индекс, то проверяем что индекс существует.

Получаем Builder :

        $conn = (new DataModel())->connection;
        $builder = Schema::connection($conn);

проверяем что миграция не была применена (проверяем что миграция может быть выполнена):

        $isExists = $builder->hasColumn(
            'data_model',
            'deleted_at'
        );

Если миграция может быть выполнена, то выполняем:

        if (!$isExists) {
            $builder->table(
                'data_model',
                function (Blueprint $table) {
                    $table->softDeletesTz();
                }
            );
        }

Аналогично с таблицами - проверяем что таблица не существует, с индексами - проверяем что индекс не существует, с индексами посложней, но можно, поможет такой код:

        $alias = (new DataModel())->connection;
        $builder = Schema
            ::connection($alias)
            ->getConnection()
            ->getDoctrineSchemaManager();

$existingIndexes = $builder->listTableIndexes('data_model');

С индексами в Laravel есть заморочка, если мы создали индекс как:

Blueprint::unique('index_name');

То и удалять надо как:

Blueprint::dropUnique('index_name');

С таблицами и колонками у Laravel ок, с индексами похуже, с триггерами совсем плохо, приходиться писать на чистом SQL, наверное я чего то не знаю о Laravel ? Адепты, подскажите !

Накатываем чистым SQL, пишем так:

DROP TRIGGER IF EXISTS trigger_name
    ON public.data_model;
CREATE TRIGGER trigger_name
    BEFORE INSERT
    ON public.data_model
    FOR EACH ROW
    EXECUTE PROCEDURE public.function_name();

Когда откатываем, пишем так же:

DROP TRIGGER IF EXISTS trigger_name
    ON public.data_model;

Правило второе: "шаблонные имена"

Миграций в проекте сотни, за полгода было написано 1000+ миграций. Конечно вся 1000 не лежит в одной директории, они раскиданы по директориям модулей.

Но тем нем нее, когда открываешь директорию в которой 50+ миграций, тебе сложно ориентироваться в них без "хороших" имён.

Соглашения об именах

Если создаём таблицу, то имя миграции начинается с create, если меняем таблицу то alter, если удаляем таблицу, то drop.

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

alter_data_model_add_property_column
alter_data_model_alter_property_column_to_text
alter_data_model_alter_property_column_set_default_value
alter_data_model_create_index_on_code_type_columns
alter_data_model_create_unique_index_on_code_column

Дропать таблицы, конечно, можно только на этапе MVP.

Команды для создания миграций:

# делаем миграцию для создания таблицы
php artisan make:migration create_profile_table --create=profile

# делаем миграцию для изменения таблицы
php artisan make:migration add_confirmed_to_profile --table=profile

Файл миграции будет помещён в директорию database/migrations собственно приложения, у нас каждый сервис это отдельный пакет и после создания файла миграции его надо переложить в директорию своего пакета.

Правило третье: таблицы и колонки дропать нельзя, все колонки nullable()

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

Откатывать миграции вместе с репозиторием, эта так себе занятие.

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

Соответственно при посеве данных, что бы не подменять файлы данных для посева, не прописывать какие конкретно колонки мы пишем - мы должны делать запись только в те колонки которые существуют:

            $columns = Schema
            ::connection((new DataModel())->connection)
            ->getConnection()
            ->getDoctrineSchemaManager()
            ->listTableColumns($(new DataModel())->getTable());

            $data = [];
            foreach ($columns as $column) {
                $name = $column->getName();
/* @var array[] $record строка данных для посева*/
                $exists = key_exists($name, $record);
                if ($exists) {
                    $data[$name] = $record[$name];
                }
            }

            $isSuccess = DataModel
                ::withTrashed()
                ->updateOrCreate(
                    ['uniqe_index_column' => $data['uniqe_index_column'],],
                    $data
                )->exists;

Правило четвёртое: значения по умолчанию, там где null недопустим

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

Либо можно в коде использовать какое то значение по умолчанию, но я такой способ не люблю, потому что это хард код, и это убивает гибкость нашего приложения. Работа приложения должна настраиваться или через переменные окружения, или файлы конфигов, или записи БД.

Введение

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

Фасад Schema обеспечивает независимую от базы данных поддержку для создания и управления таблицами во всех поддерживаемых Laravel системах баз данных. В обычной ситуации, этот фасад используется для создания и изменения таблиц / столбцов базы данных во время миграции.

Генерация миграций

Чтобы сгенерировать новую миграцию базы данных, используйте команду make:migration Artisan. Эта команда поместит новый класс миграции в каталог database/migrations вашего приложения. Каждое имя файла миграции содержит временную метку, которая позволяет Laravel определять порядок применения миграций:

php artisan make:migration create_flights_table

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

Если вы хотите указать собственный путь для сгенерированной миграции, вы можете использовать параметр --path при выполнении команды make:migration. Указанный путь должен быть относительно базового пути вашего приложения.

{tip} Заготовки миграции можно настроить с помощью публикации заготовок.

Сжатие миграций

По мере создания приложения вы можете со временем накапливать все больше и больше миграций. Это может привести к тому, что ваш каталог database/migrations станет раздутым из-за потенциально сотен миграций. Если хотите, то можете «сжать» свои миграции в один файл SQL. Для начала выполните команду schema:dump:

php artisan schema:dump

// Выгрузить текущую схему БД и удалить все существующие миграции ...
php artisan schema:dump --prune

Когда вы выполните эту команду, Laravel запишет файл «схемы» в каталог database/schema вашего приложения. Теперь, когда вы попытаетесь перенести свою базу данных, Laravel сначала выполнит SQL-операторы файла схемы, при условии, что никакие другие миграции не выполнялись. После выполнения команд файла схемы, Laravel выполнит все оставшиеся миграции, которые не были включены в дамп схемы БД.

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

{note} Сжатие миграции доступно только для баз данных MySQL, PostgreSQL и SQLite и использует клиент командной строки базы данных. Дампы схемы не могут быть восстановлены в базах данных SQLite, хранимых в памяти.

Структура миграций

Класс миграции содержит два метода: up и down. Метод up используется для добавления новых таблиц, столбцов или индексов в вашу базу данных, тогда как метод down должен отменять операции, выполняемые методом up.

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

id();
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    /**
     * Обратить миграции.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('flights');
    }
}

Указание соединения миграции

Если ваша миграция будет использовать соединение с базой данных, отличное от соединения с базой данных по умолчанию для вашего приложения, то необходимо установить свойство $connection миграции:

/**
 * Соединение с БД, которое должно использоваться миграцией.
 *
 * @var string
 */
protected $connection = 'pgsql';

/**
 * Запустить миграцию.
 *
 * @return void
 */
public function up()
{
    //
}

Запуск миграций

Чтобы запустить все незавершенные миграции, выполните команду migrate Artisan:

php artisan migrate

Если вы хотите узнать, какие миграции уже выполнены, то вы можете использовать команду migrate:status Artisan:

php artisan migrate:status

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

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

php artisan migrate --force

Откат миграций

Чтобы откатить последнюю операцию миграции, вы можете использовать команду rollback Artisan. Эта команда откатывает последний «пакет» миграций, который может включать несколько файлов миграции:

php artisan migrate:rollback

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

php artisan migrate:rollback --step=5

Команда migrate:reset откатит все миграции вашего приложения:

php artisan migrate:reset

Откат и миграция с помощью одной команды

Команда migrate:refresh откатит все ваши миграции, а затем выполнит команду migrate. Эта команда эффективно воссоздает всю вашу базу данных:

php artisan migrate:refresh

// Обновляем базу данных и запускаем все наполнители базы данных ...
php artisan migrate:refresh --seed

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

php artisan migrate:refresh --step=5

Удаление всех таблиц с последующей миграцией

Команда migrate:fresh удалит все таблицы из базы данных, а затем выполнит команду migrate:

php artisan migrate:fresh

php artisan migrate:fresh --seed

{note} Команда migrate:fresh удалит все таблицы базы данных независимо от их префикса. Эту команду следует использовать с осторожностью при разработке в базе данных, которая используется совместно с другими приложениями.

Таблицы

Создание таблиц

Чтобы создать новую таблицу базы данных, используйте метод create фасада Schema. Метод create принимает два аргумента: первый – это имя таблицы, а второй – замыкание, которое получает объект Blueprint, используемый для определения новой таблицы:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email');
    $table->timestamps();
});

При создании таблицы вы можете использовать любой из методов столбцов построителя схемы для определения столбцов таблицы.

Проверка наличия таблицы / столбца

Вы можете проверить наличие таблицы или столбца с помощью методов hasTable и hasColumn, соответственно:

if (Schema::hasTable('users')) {
    // Таблица `users` существует ...
}

if (Schema::hasColumn('users', 'email')) {
    // Таблица `users` существует и содержит столбец `email` ...
}

Соединение с базой данных и параметры таблицы

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

Schema::connection('sqlite')->create('users', function (Blueprint $table) {
    $table->id();
});

Кроме того, некоторые другие свойства и методы могут использоваться для определения других аспектов создания таблицы. Свойство engine используется для указания механизма хранения таблицы при использовании MySQL:

Schema::create('users', function (Blueprint $table) {
    $table->engine = 'InnoDB';

    // ...
});

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

Schema::create('users', function (Blueprint $table) {
    $table->charset = 'utf8mb4';
    $table->collation = 'utf8mb4_unicode_ci';

    // ...
});

Метод temporary используется, чтобы указать, что таблица должна быть «временной». Временные таблицы видны только текущему сеансу соединения базы данных и автоматически удаляются при закрытии соединения:

Schema::create('calculations', function (Blueprint $table) {
    $table->temporary();

    // ...
});

Обновление таблиц

Метод table фасада Schema используется для обновления существующих таблиц. Подобно методу create, метод table принимает два аргумента: имя таблицы и замыкание, которое получает экземпляр Blueprint, используемый для добавления столбцов или индексов в таблицу:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes');
});

Переименование / удаление таблиц

Чтобы переименовать существующую таблицу базы данных, используйте метод rename:

use Illuminate\Support\Facades\Schema;

Schema::rename($from, $to);

Чтобы удалить существующую таблицу, вы можете использовать методы drop или dropIfExists:

Schema::drop('users');

Schema::dropIfExists('users');

Переименование таблиц с внешними ключами

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

Столбцы

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

Метод table фасада Schema используется для обновления существующих таблиц. Как и метод create, метод table принимает два аргумента: имя таблицы и замыкание, которое получает экземпляр Illuminate\Database\Schema\Blueprint, используемый для добавления столбцов в таблицу:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes');
});

Доступные типы столбцов

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

  • bigIncrements
  • bigInteger
  • binary
  • boolean
  • char
  • dateTimeTz
  • dateTime
  • date
  • decimal
  • double
  • enum
  • float
  • foreignId
  • geometryCollection
  • geometry
  • id
  • increments
  • integer
  • ipAddress
  • json
  • jsonb
  • lineString
  • longText
  • macAddress
  • mediumIncrements
  • mediumInteger
  • mediumText
  • morphs
  • multiLineString
  • multiPoint
  • multiPolygon
  • nullableMorphs
  • nullableTimestamps
  • nullableUuidMorphs
  • point
  • polygon
  • rememberToken
  • set
  • smallIncrements
  • smallInteger
  • softDeletesTz
  • softDeletes
  • string
  • text
  • timeTz
  • time
  • timestampTz
  • timestamp
  • timestampsTz
  • timestamps
  • tinyIncrements
  • tinyInteger
  • unsignedBigInteger
  • unsignedDecimal
  • unsignedInteger
  • unsignedMediumInteger
  • unsignedSmallInteger
  • unsignedTinyInteger
  • uuidMorphs
  • uuid
  • year

bigIncrements()

Метод bigIncrements создает эквивалент автоинкрементного столбца UNSIGNED BIGINT (первичный ключ):

$table->bigIncrements('id');

bigInteger()

Метод bigInteger создает эквивалент столбца BIGINT:

$table->bigInteger('votes');

binary()

Метод binary создает эквивалент столбца BLOB:

$table->binary('photo');

boolean()

Метод boolean создает эквивалент столбца BOOLEAN:

$table->boolean('confirmed');

char()

Метод char создает эквивалент столбца CHAR указанной длины:

$table->char('name', 100);

dateTimeTz()

Метод dateTimeTz создает эквивалент столбца DATETIME (с часовым поясом) с необязательной точностью (общее количество цифр):

$table->dateTimeTz('created_at', $precision = 0);

dateTime()

Метод dateTime создает эквивалент столбца DATETIME с необязательной точностью (общее количество цифр):

$table->dateTime('created_at', $precision = 0);

date()

Метод date создает эквивалент столбца DATE:

$table->date('created_at');

decimal()

Метод decimal создает эквивалент столбца DECIMAL с точностью (общее количество цифр) и масштабом (десятичные цифры):

$table->decimal('amount', $precision = 8, $scale = 2);

double()

Метод double создает эквивалент столбца DOUBLE с точностью (общее количество цифр) и масштабом (десятичные цифры):

$table->double('amount', 8, 2);

enum()

Метод enum создает эквивалент столбца ENUM с указанием допустимых значений:

$table->enum('difficulty', ['easy', 'hard']);

float()

Метод float создает эквивалент столбца FLOAT с точностью (общее количество цифр) и масштабом (десятичные цифры):

$table->float('amount', 8, 2);

foreignId()

Метод foreignId является псевдонимом метода unsignedBigInteger:

$table->foreignId('user_id');

geometryCollection()

Метод geometryCollection создает эквивалент столбца GEOMETRYCOLLECTION:

$table->geometryCollection('positions');

geometry()

Метод geometry создает эквивалент столбца GEOMETRY:

$table->geometry('positions');

id()

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

$table->id();

increments()

Метод increments создает эквивалент автоинкрементного столбца UNSIGNED INTEGER в качестве первичного ключа:

$table->increments('id');

integer()

Метод integer создает эквивалент столбца INTEGER:

$table->integer('votes');

ipAddress()

Метод ipAddress создает эквивалент столбца INTEGER:

$table->ipAddress('visitor');

json()

Метод json создает эквивалент столбца JSON:

$table->json('options');

jsonb()

Метод jsonb создает эквивалент столбца JSONB:

$table->jsonb('options');

lineString()

Метод lineString создает эквивалент столбца LINESTRING:

$table->lineString('positions');

longText()

Метод longText создает эквивалент столбца LONGTEXT:

$table->longText('description');

macAddress()

Метод macAddress создает столбец, предназначенный для хранения MAC-адреса. Некоторые системы баз данных, такие как PostgreSQL, имеют специальный тип столбца для этого типа данных. Другие системы баз данных будут использовать столбец строкового эквивалента:

$table->macAddress('device');

mediumIncrements()

Метод mediumIncrements создает эквивалент автоинкрементного столбца UNSIGNED MEDIUMINT в качестве первичного ключа:

$table->mediumIncrements('id');

mediumInteger()

Метод mediumInteger создает эквивалент столбца MEDIUMINT:

$table->mediumInteger('votes');

mediumText()

Метод mediumText создает эквивалент столбца MEDIUMTEXT:

$table->mediumText('description');

morphs()

Метод morphs – это удобный метод, который добавляет эквивалент столбца UNSIGNED BIGINT ({column}_id) и эквивалент столбца VARCHAR ({column}_type).

Этот метод предназначен для использования при определении столбцов, необходимых для полиморфного отношения Eloquent. В следующем примере будут созданы столбцы taggable_id и taggable_type:

$table->morphs('taggable');

multiLineString()

Метод multiLineString создает эквивалент столбца MULTILINESTRING:

$table->multiLineString('positions');

multiPoint()

Метод multiPoint создает эквивалент столбца MULTIPOINT:

$table->multiPoint('positions');

multiPolygon()

Метод multiPolygon создает эквивалент столбца MULTIPOLYGON:

$table->multiPolygon('positions');

nullableTimestamps()

Метод аналогичен методу timestamps; тем не менее, создаваемый столбец будет иметь значение NULL:

$table->nullableTimestamps(0);

nullableMorphs()

Метод аналогичен методу morphs; тем не менее, создаваемый столбец будет иметь значение NULL:

$table->nullableMorphs('taggable');

nullableUuidMorphs()

Метод аналогичен методу uuidMorphs; тем не менее, создаваемый столбец будет иметь значение NULL:

$table->nullableUuidMorphs('taggable');

point()

Метод point создает эквивалент столбца POINT:

$table->point('position');

polygon()

Метод polygon создает эквивалент столбца POLYGON:

$table->polygon('position');

rememberToken()

Метод rememberToken создает NULL-эквивалент столбца VARCHAR(100), предназначенный для хранения текущего токена аутентификации:

$table->rememberToken();

set()

Метод set создает эквивалент столбца SET с заданным списком допустимых значений:

$table->set('flavors', ['strawberry', 'vanilla']);

smallIncrements()

Метод smallIncrements создает эквивалент автоинкрементного столбца UNSIGNED SMALLINT в качестве первичного ключа:

$table->smallIncrements('id');

smallInteger()

Метод smallInteger создает эквивалент столбца SMALLINT:

$table->smallInteger('votes');

softDeletesTz()

Метод softDeletesTz добавляет NULL-эквивалент столбца TIMESTAMP (с часовым поясом) с необязательной точностью (общее количество цифр). Этот столбец предназначен для хранения временной метки deleted_at, необходимой для функции «программного удаления» Eloquent:

$table->softDeletesTz($column = 'deleted_at', $precision = 0);

softDeletes()

Метод softDeletes добавляет NULL-эквивалент столбца TIMESTAMP с необязательной точностью (общее количество цифр). Этот столбец предназначен для хранения временной метки deleted_at, необходимой для функции «программного удаления» Eloquent:

$table->softDeletes($column = 'deleted_at', $precision = 0);

string()

Метод string создает эквивалент столбца VARCHAR указанной длины:

$table->string('name', 100);

text()

Метод text создает эквивалент столбца TEXT:

$table->text('description');

timeTz()

Метод timeTz создает эквивалент столбца TIME (с часовым поясом) с необязательной точностью (общее количество цифр):

$table->timeTz('sunrise', $precision = 0);

time()

Метод time создает эквивалент столбца TIME с необязательной точностью (общее количество цифр):

$table->time('sunrise', $precision = 0);

timestampTz()

Метод timestampTz создает эквивалент столбца TIMESTAMP (с часовым поясом) с необязательной точностью (общее количество цифр):

$table->timestampTz('added_at', $precision = 0);

timestamp()

Метод timestamp создает эквивалент столбца TIMESTAMP с необязательной точностью (общее количество цифр):

$table->timestamp('added_at', $precision = 0);

timestampsTz()

Метод timestampsTz создает столбцы created_at и updated_at, эквивалентные TIMESTAMP (с часовым поясом) с необязательной точностью (общее количество цифр):

$table->timestampsTz($precision = 0);

timestamps()

Метод timestamps method creates created_at and updated_at TIMESTAMP с необязательной точностью (общее количество цифр):

$table->timestamps($precision = 0);

tinyIncrements()

Метод tinyIncrements создает эквивалент автоинкрементного столбца UNSIGNED TINYINT в качестве первичного ключа:

$table->tinyIncrements('id');

tinyInteger()

Метод tinyInteger создает эквивалент столбца TINYINT:

$table->tinyInteger('votes');

unsignedBigInteger()

Метод unsignedBigInteger создает эквивалент столбца UNSIGNED BIGINT:

$table->unsignedBigInteger('votes');

unsignedDecimal()

Метод unsignedDecimal создает эквивалент столбца UNSIGNED DECIMAL с необязательной точностью (общее количество цифр) и масштабом (десятичные цифры):

$table->unsignedDecimal('amount', $precision = 8, $scale = 2);

unsignedInteger()

Метод unsignedInteger создает эквивалент столбца UNSIGNED INTEGER:

$table->unsignedInteger('votes');

unsignedMediumInteger()

Метод unsignedMediumInteger создает эквивалент столбца UNSIGNED MEDIUMINT:

$table->unsignedMediumInteger('votes');

unsignedSmallInteger()

Метод unsignedSmallInteger создает эквивалент столбца UNSIGNED SMALLINT:

$table->unsignedSmallInteger('votes');

unsignedTinyInteger()

Метод unsignedTinyInteger создает эквивалент столбца UNSIGNED TINYINT:

$table->unsignedTinyInteger('votes');

uuidMorphs()

Метод uuidMorphs – это удобный метод, который добавляет эквивалент столбца CHAR(36) ({column}_id) и эквивалент столбца VARCHAR ({column}_type).

Этот метод предназначен для использования при определении столбцов, необходимых для полиморфного отношения Eloquent, использующего идентификаторы UUID. В следующем примере будут созданы столбцы taggable_id и taggable_type:

$table->uuidMorphs('taggable');

uuid()

Метод uuid создает эквивалент столбца UUID:

$table->uuid('id');

year()

Метод year создает эквивалент столбца YEAR:

$table->year('birth_year');

Модификаторы столбца

В дополнение к типам столбцов, перечисленным выше, есть несколько «модификаторов» столбцов, которые вы можете использовать при добавлении столбца в таблицу базы данных. Например, чтобы сделать столбец «допускающим значение NULL», вы можете использовать метод nullable:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->string('email')->nullable();
});

В следующей таблице представлены все доступные модификаторы столбцов. В этот список не входят модификаторы индексов:

Модификатор Описание
->after('column') Поместить столбец «после» другого столбца (MySQL).
->autoIncrement() Установить столбцы INTEGER как автоинкрементные (первичный ключ).
->charset('utf8mb4') Указать набор символов для столбца (MySQL).
->collation('utf8mb4_unicode_ci') Указать параметры сравнения для столбца (MySQL/PostgreSQL/SQL Server).
->comment('my comment') Добавить комментарий к столбцу (MySQL/PostgreSQL).
->default($value) Указать значение «по умолчанию» для столбца.
->first() Поместить столбец «первым» в таблице (MySQL).
->from($integer) Установить начальное значение автоинкрементного поля (MySQL / PostgreSQL).
->nullable($value = true) Позволить (по умолчанию) значения NULL для вставки в столбец.
->storedAs($expression) Создать сохраненный генерируемый столбец (MySQL).
->unsigned() Установить столбцы INTEGER как UNSIGNED (MySQL).
->useCurrent() Установить столбцы TIMESTAMP для использования CURRENT_TIMESTAMP в качестве значения по умолчанию.
->useCurrentOnUpdate() Установить столбцы TIMESTAMP для использования CURRENT_TIMESTAMP при обновлении записи.
->virtualAs($expression) Создать виртуальный генерируемый столбец (MySQL).
->generatedAs($expression) Создать столбец идентификаторов с указанными параметрами последовательности (PostgreSQL).
->always() Определить приоритет значений последовательности над вводом для столбца идентификаторов (PostgreSQL).

Выражения для значений по умолчанию

Модификатор default принимает значение или экземпляр Illuminate\Database\Query\Expression. Использование экземпляра Expression не позволит Laravel заключить значение в кавычки и позволит вам использовать функции, специфичные для базы данных. Одна из ситуаций, когда это особенно полезно, когда вам нужно назначить значения по умолчанию для столбцов JSON:

id();
            $table->json('movies')->default(new Expression('(JSON_ARRAY())'));
            $table->timestamps();
        });
    }
}

{note} Поддержка выражений по умолчанию зависит от вашего драйвера базы данных, версии базы данных и типа поля. См. документацию к вашей базе данных.

Порядок столбцов

Метод after добавляет набор столбцов после указанного существующего столбца в схеме базы данных MySQL:

$table->after('password', function ($table) {
    $table->string('address_line1');
    $table->string('address_line2');
    $table->string('city');
});

Изменение столбцов

Необходимые компоненты

Перед изменением столбца вы должны установить пакет doctrine/dbal с помощью менеджера пакетов Composer. Библиотека Doctrine DBAL используется для определения текущего состояния столбца и для создания запросов SQL, необходимых для внесения запрошенных изменений в столбец:

composer require doctrine/dbal

Если вы планируете изменять столбцы, созданные с помощью метода timestamp, вы также должны добавить следующую конфигурацию в файл config/database.php вашего приложения:

use Illuminate\Database\DBAL\TimestampType;

'dbal' => [
    'types' => [
        'timestamp' => TimestampType::class,
    ],
],

{note} Если ваше приложение использует Microsoft SQL Server, то убедитесь, что вы установили doctrine/dbal:^3.0.

Обновление атрибутов столбца

Метод change позволяет вам изменять тип и атрибуты существующих столбцов. Например, вы можете увеличить размер string столбца. Чтобы увидеть метод change в действии, давайте увеличим размер столбца name до 50. Для этого мы просто определяем новое состояние столбца и затем вызываем метод change:

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change();
});

Мы также можем изменить столбец, чтобы он допускал значение NULL:

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->nullable()->change();
});

{note} Только следующие типы столбцов могут быть изменены: bigInteger, binary, boolean, date, dateTime, dateTimeTz, decimal, integer, json, longText, mediumText, smallInteger, string, text, time, unsignedBigInteger, unsignedInteger, unsignedSmallInteger, и uuid.

Переименование столбцов

Чтобы переименовать столбец, вы можете использовать метод renameColumn построителя схемы Blueprint. Перед переименованием столбца убедитесь, что вы установили библиотеку doctrine/dbal через менеджер пакетов Composer:

Schema::table('users', function (Blueprint $table) {
    $table->renameColumn('from', 'to');
});

{note} Переименование enum столбца в настоящее время не поддерживается.

Удаление столбцов

Чтобы удалить столбец, вы можете использовать метод dropColumn построителя схемы Blueprint. Если ваше приложение использует базу данных SQLite, то вы должны установить библиотеку doctrine/dbal через менеджер пакетов Composer, прежде чем использовать метод dropColumn:

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn('votes');
});

Вы можете удалить несколько столбцов из таблицы, передав массив имен столбцов методу dropColumn:

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn(['votes', 'avatar', 'location']);
});

{note} Удаление или изменение нескольких столбцов в рамках одной миграции при использовании базы данных SQLite не поддерживается.

Доступные псевдонимы команд

Laravel содержит несколько удобных методов, связанных с удалением общих типов столбцов. Каждый из этих методов описан в таблице ниже:

Команда Описание
$table->dropMorphs('morphable'); Удалить столбцы morphable_id и morphable_type.
$table->dropRememberToken(); Удалить столбец remember_token.
$table->dropSoftDeletes(); Удалить столбец deleted_at.
$table->dropSoftDeletesTz(); Псевдоним dropSoftDeletes().
$table->dropTimestamps(); Удалить столбцы created_at и updated_at.
$table->dropTimestampsTz(); Псевдоним dropTimestamps().

Введение

Многие веб-приложения требуют, чтобы пользователи подтверждали свои адреса электронной почты перед использованием приложения. Вместо того, чтобы заставлять вас повторно внедрять это в каждом приложении, Laravel предоставляет удобные методы для отправки и проверки адреса электронной почты пользователя.

Подготовка модели

Для начала убедитесь, что ваша модель App\User реализует контракт Illuminate\Contracts\Auth\MustVerifyEmail:

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;

    
}

Настройки базы данных

Столбец подтверждения Email

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

php artisan migrate

Роутинг

Laravel включает класс Auth\VerificationController, который содержит необходимую логику для отправки ссылок подтверждения email и проверки электронной почты. Чтобы зарегистрировать необходимые роуты для этого контроллера, передайте опцию verify методу Auth::routes

Auth::routes(['verify' => true]);

Защита роутов

Посредников роута (Route middleware) можно использовать, чтобы разрешить доступ только проверенным пользователям к данному роуту. Laravel поставляется с посредником verified, который определен в Illuminate\Auth\Middleware\EnsureEmailIsVerified. Поскольку это посредник уже зарегистрирован в app/Http/Kernel.php вашего приложения, все, что вам нужно сделать, это подключить посредника к определению роута:

Route::get('profile', function () {
    
})->middleware('verified');

Шаблоны

Для того чтобы сгенерировать все необходимые шаблоны для подтверждения электронной почты, Вы можете использовать пакет laravel/ui для Composer:

composer require laravel/ui  "^1.2" --dev

php artisan ui vue --auth

Шаблон подтверждения email адреса находится в resources/views/auth/verify.blade.php. Вы можете изменять его на свое усмотрение.

Действие после подтверждения Email

После проверки адреса электронной почты пользователь будет автоматически перенаправлен на URL /home. Вы можете настроить местоположение перенаправления после проверки, определив метод или свойство redirectTo в VerificationController:

protected $redirectTo = '/dashboard';

Выбираем стек

Laravel Jetstream поставляется с двумя стеками для фронтенда — Livewire и Inertia.js. Оба стека добавляют реактивности в ваше приложение, разница между ними в том, что Livewire в качестве шаблонизатора использует Blade, а Inertia.js использует Vue. В качестве CSS-фреймворка в обоих случаях используется Tailwind.

Установка

Если мы создаем новый проект, то можем использовать Laravel Installer с флагом --jet. Установка будет интерактивной и предложит выбрать стек и управление командами (teams). После установки требуется выполнить миграции в базу данных:

laravel new project-name --jet
php artisan migrate

В готовый проект следует добавить пакет с помощью Composer:

composer require laravel/jetstream

Далее в зависимости от выбранного стека выбираем одно из двух. Если управление командами не требуется, то флаг --teams нужно убрать.

Livewire:

php artisan jetstream:install livewire --teams

Inertia.js:

php artisan jetstream:install inertia --teams

Завершаем установку установкой NPM-пакетов и миграцией базы:

npm install && npm run dev
php artisan migrate

Профиль пользователя

Laravel Jetstream позволяет пользователю заходить в свой профиль, обновлять информацию о себе и даже загружать фото. Отключить возможность установки фотографий можно в config/jetstream.php
image

Двухфакторная аутентификация

После включении двухфакторной аутентификации пользователь должен сохранить коды восстановления, а также отсканировать полученный QR-код с помощью приложения с поддержкой One-Time Password — динамического пароля. Это может быть, например, Google Authenticator или 1Password.
image

API

Jetstream интегрирован с Sanctum и позволяет пользователю генерировать токены доступа с различными правами: создание, чтение, обновление и удаление. Отключить эту возможность можно в config/jetstream.php
image

Создание миграции

Для создания миграции используйте команду Artisan под названием "make:migration":

php artisan make:migration create_users_table

Если нужно указать свой путь для создания миграций, то используйте параметр --path при запуске команды "make:migration". Этот путь указыватся относительного баззового пути приложения.

Миграция будет создана в папке database/migrations. К ней будет сохранена метка времени, по которой Laravel поймёт в каком порядке применять миграции.

Если в миграции нужно отметить создание новой таблицы или отметить её имя, то можно использовать параметры "--table" и "--create". Эти параметры создают указанную таблицу в файле миграции:

php artisan make:migration create_users_table --create=users

php artisan make:migration add_votes_to_users_table --table=users

Структура миграций

Миграции содержат методы под названием "up" и "down". Первый используется для добавления таблиц, столбцов и индексов в базу данных. А второй отменяет операции, выполненные первым. Оба метода поддерживают использование построителя структур Laravel.

Приведём пример использования этих методов, создав таблицу "Food":

increments('id');
         $table->string('name');
         $table->string('taste');
         $table->timestamps();
     });
   }

   public function down() {
      Schema::drop('food');
   }
}?>

Выполнение миграций

Чтобы запустить все миграции выполните команду Artisan под названием "migrate":

php artisan migrate

Некоторые миграции могут приводить к потере данных. Поэтому для предотвращения случайного запуска таких миграций запрашивается подтверждение на из выполнение. Чтобы отключить подтверждение (и соглашаться со всеми изменениями), можно использовать ключ "--force":

php artisan migrate --force

При появлении ошибки "class not found" выполните команду composer dump-autoload. Затем заново запустите команду "migrate".

Откат миграций

Для отмены внесённых миграцией изменений используется команда "migrate:rollback" и "migrate:reset". Первая делает только откат последней миграции, а вторая откатывает все миграции:

php artisan migrate:rollback

php artisan migrate:reset

Если нужно откатить сразу несколько миграций (но не все), то используйте ключ "--step" для команды rollback. В значение ключа поставьте количество необходимых откатов. К примеру, откат трём миграций:

php artisan migrate:rollback --step=3

Существует ещё команда "migrate:refresh". Она отменяет изменения всех миграций, а затем выполняет команду "migrate". Как и в предыдущем случае, у этой команды есть возможность отката на определённое количество миграций. Оно указывается после ключа "--step". :

php artisan migrate:refresh

php artisan migrate:refresh --step=3

Миграция

Первый файл – миграция в директории database/migrations.

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}

Миграция – SQL-запрос, который выполняется в базе при любом её изменении. В данном случае запрос создаёт таблицу articles. Это соглашение пришло в Laravel из Rails: для каждой модели создаётся таблица, где имя модели берётся в нижнем регистре и множественном числе. Например Articlearticles или Personpeople.

Сама миграция не выглядит как SQL. Внутри неё используется библиотека, которая позволяет описывать изменения в базе в виде кода, который затем превращается в SQL. Структура этого кода достаточно проста, если знать PHP. В нём описывается таблица, все её колонки и их типы.

По умолчанию Laravel добавляют в миграцию два вызова:

  • $table->id(); – колонка, которая будет первичным ключом.
  • $table->timestamps() – два поля: updated_at (время последнего обновления) и created_at (время добавления). Это стандартная практика для многих фреймворков, эти колонки добавляются во все таблицы для удобства отслеживания дат.

Остальные колонки нужно добавлять самостоятельно. Для статей полная миграция выглядит так:

Schema::create('articles', function (Blueprint $table) {
    $table->id();
    $table->string('name'); // название статьи
    $table->text('body'); // тело статьи
    $table->timestamps();
});

Миграции не выполняются автоматически. Их нужно "применять" или, как говорят "накатывать" на базу данных. Команда php artisan migrate находит все миграции, которые ещё не были применены и выполняет их все в том порядке, в котором они расположены в файловой системе.

$ php artisan migrate
Migrating: 2020_03_21_000000_create_articles_table
Migrated:  2020_03_21_000000_create_articles_table

Если все прошло успешно, то в базе данных появилась таблица articles.

Миграции можно не только накатывать, но и откатывать. Для этого нужно набрать php artisan migrate:rollback. Эта команда попробует отменить последнюю миграцию. Повторный вызов откатит ещё одну миграцию, которая была перед последней. И так далее до самого конца.

Теперь можно переходить к модели.

Модель

Второй файл – класс (модель) с именем Article в директории app/Models

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    //
}

Модель в Laravel – это класс который наследуется от Model. В самом простом случае, этот класс не содержит ни строчки кода. Большую часть работы по его функционированию берет на себя Eloquent. Эта ORM связывает класс с таблицей в базе данных и предоставляет множество необходимых методов, которых достаточно для большинства задач.

Подробнее о том как работает модель – в следующем уроке.

Проектирование/подготовка

Разработку бота предлагаю, как и все нормальные разработчики, начать с проектирования, постановки задачи и объяснения как работает laravel. Перед этим скажу, что я пишу код в phpStrom. Можно писать в любом другом IDE, но я пользуюсь именно им.

В laravel реализован паттерн MVC(Model View Controller). Это не значит, что нужно писать только под mvc, можно и говнокодить, но лучше пользоваться теми преимуществами, которые предоставляет фреймворк. Если вы знакомы с mvc, но не применяли его, как я, то разработка с помощью laravel’a это лучший способ закрепить знания.

Что должен делать наш бот:


  • Спрашивать у пользователя его имя
  • Поинтересоваться, нравится пользователю погода или нет
  • Также записать ответ в БД
  • Попрощаться и отправить картинку

Немного о MVC. При обращение к нашему ПО, посредством команд(url адреса), мы должны принять эти команды и обработать, понять, что требуется пользователю. Для этого есть пути, так называемые routes. Routes определяет какой Controller нужно использовать, в свою очередь controller, если это требуется, обращается к БД через model. Model связывается с базой данных и возвращает нужный нам результат. В боте view не нужен, т.к. вся работа идет через интерфейс мессенджера. Тем самым, после получения данных от model’и, controller отдает эти данные view, в нашем случае это blade шаблон (именно его использует laravel). Данные можно отдать и обычной php странице, но лучше это делать через blade шаблоны. Мы используем интерфейс мессенджера, то отправлять данные будем сразу в него.