Laravel полон скрытых жемчужин, недокументированных или малоизвестных функций, опций и «хаков». Все что я нашёл, за время своей работы, я оформил в отдельную статью. Это первая её часть.
Совет 1. Вызываемые Контроллеры
Если вы хотите создать контроллер только с одним действием, вы можете использовать метод __invoke() и даже создать «вызываемый» (invokable) контроллер.
namespace App\Http\Controllers; use App\User; use App\Http\Controllers\Controller; class ShowProfile extends Controller { /** * Показать профайл данного пользователя * * @param int $id * @return Response */ public function __invoke($id) { return view('user.profile', ['user' => User::findOrFail($id)]); } }
Маршруты:
Route::get('user/{id}', 'ShowProfile');
Artisan команда для создания такого контроллера:
php artisan make:controller ShowProfile --invokable
Совет 2. Беззнаковое целое
Для внешнего ключа в миграции вместо integer() используйте unsignedInteger() или integer()->unsigned(), в противном случае вы можете получить ошибку SQL.
Schema::create('employees', function (Blueprint $table) { $table->unsignedInteger('company_id'); $table->foreign('company_id')->references('id')->on('companies'); // ... });
Совет 3. OrderBy в отношениях Eloquent
Вы можете указывать orderBy() прямо в определении отношений.
public function products() { return $this->hasMany(Product::class); } public function productsByName() { return $this->hasMany(Product::class)->orderBy('name'); }
Совет 4. Порядок миграций
Если вы хотите изменить порядок миграций в БД, просто переименуйте временную метку файла, например 2018_08_04_070443_create_posts_table.php в 2018_07_04_070443_create_posts_table.php (изменено с 2018_08_04 на 2018_07_04). Они запускаются в алфавитном порядке.
Совет 5. Сырые запросы к БД
Вы можете использовать сырые запросы к базе данных в различных местах, включая функцию havingRaw() после groupBy().
Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();
Совет 6. переменная $loop в foreach
Внутри цикла foreach вы можете проверить является ли текущая запись первой/последней, просто используя переменную $loop.
@foreach ($users as $user) @if ($loop->first) Это первая итерация. @endif @if ($loop->last) Это последняя итерация. @endif <p>Это пользователь {{ $user->id }}</p> @endforeach
У неё есть и другие свойства, например, $loop->iteration или $loop->count.
Подробнее здесь: https://laravel.com/docs/master/blade#the-loop-variable
Совет 7. Методы where для времени в Eloquent
В Eloquent вы можете проверьте дату с помощью функций whereDay(), whereMonth(), whereYear(), whereDate() и whereTime().
$products = Product::whereDate('created_at', '2018-01-31')->get(); $products = Product::whereMonth('created_at', '12')->get(); $products = Product::whereDay('created_at', '31')->get(); $products = Product::whereYear('created_at', date('Y'))->get(); $products = Product::whereTime('created_at', '=', '14:13:58')->get();
Совет 8. Группа маршрутов внутри группы
В маршрутах можно создать группу внутри группы, назначив определенный мидлвар только некоторым URL-адресам в «родительской» группе.
Route::group(['prefix' => 'account', 'as' => 'account.'], function() { Route::get('login', 'AccountController@login'); Route::get('register', 'AccountController@register'); Route::group(['middleware' => 'auth'], function() { Route::get('edit', 'AccountController@edit'); }); })
Совет 9. Инкременты и декременты
Если вы хотите инкрементировать значение поля в таблице, просто используйте функцию increment(). Можно увеличивать не только на 1, но и на нужно вам число, например, 50.
Post::find($post_id)->increment('view_count'); User::find($user_id)->increment('points', 50);
Совет 10. Существует ли шаблон?
Вы можете проверить, существует ли файл шаблона, прежде чем загрузить его.
if (view()->exists('custom.page')) { // Загрузить шаблон }
Вы даже можете определить массив шаблонов, и только первый найденный будет загружен фактически.
return view()->first(['custom.dashboard', 'dashboard'], $data);
Совет 11. Без полей меток времени
Если ваша таблица не содержит полей меток времени created_at и updated_at, вы можете указать модели Eloquent, через $timestamps = false, что бы она их не использовала.
class Company extends Model { public $timestamps = false; }
Совет 12. Поля миграции с часовыми поясами
Знаете ли вы, что в миграциях есть не только timestamps(), но и timestampsTz() для часового пояса.
Schema::create('employees', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email'); $table->timestampsTz(); });
Кроме того, есть dateTimeTz(), timeTz(), timestampTz(), softDeletesTz().
Совет 13. Eloquent метод has() еще глубже
Вы можете использовать функцию has() для запроса отношений на глубину в два слоя!
// Author -> hasMany(Book::class); // Book -> hasMany(Rating::class); $authors = Author::has('books.ratings')->get();
Совет 14. Типы полей миграций
Есть несколько интересных типы полей, например:
$table->geometry('positions'); $table->ipAddress('visitor'); $table->macAddress('device'); $table->point('position'); $table->uuid('id');
Просмотреть все типы: https://laravel.com/docs/master/migrations#creating-column
Совет 15. Справка по команде Artisan
Чтобы узнать параметры команды artisan, выполните её с флагом —help:
php artisan make:model --help
Параметры:
-a, --all — Генерирует миграцию, фабрику и контроллер ресурсов для модели -c, --controller — создает новый контроллер для модели -f, --factory — создает новую фабрику для модели --force — принудительное создание класса, даже если модель уже существует. -m, --migration — создает новый файл миграции для модели. -p, --pivot — указывает, должна ли создаваемая модель быть пользовательской моделью промежуточной таблицы. -r, --resource — указывает, должен ли сгенерированный контроллер быть контроллером ресурсов. -h, --help — показывает эту справку -q, --quiet — не выводить никаких сообщений -V, --version — показыает версии приложения --ansi — включить вывод ANSI --ansi — включить вывод ANSI --no-ansi — отключить вывод ANSI -n, --no-interaction — не задавать интерактивных вопросов -- env[=ENV] — среда, в которой должна выполниться команда - v|vv|vvv, --verbose — объем отображаемых сообщений: 1 - нормальный вывод, 2 - подробный вывод и 3 — отладка
Совет 16. Временная Метка по умолчанию
При создании миграций вы можете использовать типа поля ->timestamp() с параметром ->useCurrent(), который выставит дефолтным значением CURRENT_TIMESTAMP.
$table->timestamp('created_at')->useCurrent(); $table->timestamp('updated_at')->useCurrent();
Совет 17. Установка залогиненного пользователя через Наблюдателя
Используйте make:observer и метод creating() для автоматической установки поля user_id для залогиненного пользователя.
class PostObserver { /** * Обрабатываем событие «создание» записи. * * @param \App\Post $post * @return void */ public function creating(Post $post) { $post->user_id = auth()->id(); } }
Совет 18. Мягкое удаление: множественное восстановление
При использовании мягкого удаления (soft-deletes) вы можете восстановить одним запросом разом несколько записей.
Post::withTrashed()->where('author_id', 1)->restore();
Совет 19. HasMany() — имеет много, а сколько именно?
В Eloquent отношении hasMany() вы можете отфильтровать записи, которые имеют X дочерних записей.
// Author -> hasMany(Book::class) $authors = Author::has('books', '>', 5)->get();
Совет 20. Валидация изображения
При проверке загруженных изображений можно указать требуемые размеры:
'photo' => 'dimensions:max_width=4096,max_height=4096'
Продолжение: Советы по Laravel. Часть 2.
Автор: Povilas Korop
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.