Laravel полон скрытых жемчужин, недокументированных или малоизвестных функций, опций и «хаков». Все что я нашёл, за время своей работы, я оформил в отдельную статью. Это первая её часть.
Если вы хотите создать контроллер только с одним действием, вы можете использовать метод __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
Для внешнего ключа в миграции вместо integer() используйте unsignedInteger() или integer()->unsigned(), в противном случае вы можете получить ошибку SQL.
Schema::create('employees', function (Blueprint $table) {
$table->unsignedInteger('company_id');
$table->foreign('company_id')->references('id')->on('companies');
// ...
});
Вы можете указывать orderBy() прямо в определении отношений.
public function products()
{
return $this->hasMany(Product::class);
}
public function productsByName()
{
return $this->hasMany(Product::class)->orderBy('name');
}
Если вы хотите изменить порядок миграций в БД, просто переименуйте временную метку файла, например 2018_08_04_070443_create_posts_table.php в 2018_07_04_070443_create_posts_table.php (изменено с 2018_08_04 на 2018_07_04). Они запускаются в алфавитном порядке.
Вы можете использовать сырые запросы к базе данных в различных местах, включая функцию havingRaw() после groupBy().
Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();
Внутри цикла 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
В 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();
В маршрутах можно создать группу внутри группы, назначив определенный мидлвар только некоторым 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');
});
})
Если вы хотите инкрементировать значение поля в таблице, просто используйте функцию increment(). Можно увеличивать не только на 1, но и на нужно вам число, например, 50.
Post::find($post_id)->increment('view_count');
User::find($user_id)->increment('points', 50);
Вы можете проверить, существует ли файл шаблона, прежде чем загрузить его.
if (view()->exists('custom.page')) {
// Загрузить шаблон
}
Вы даже можете определить массив шаблонов, и только первый найденный будет загружен фактически.
return view()->first(['custom.dashboard', 'dashboard'], $data);
Если ваша таблица не содержит полей меток времени created_at и updated_at, вы можете указать модели Eloquent, через $timestamps = false, что бы она их не использовала.
class Company extends Model
{
public $timestamps = false;
}
Знаете ли вы, что в миграциях есть не только timestamps(), но и timestampsTz() для часового пояса.
Schema::create('employees', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->timestampsTz();
});
Кроме того, есть dateTimeTz(), timeTz(), timestampTz(), softDeletesTz().
Вы можете использовать функцию has() для запроса отношений на глубину в два слоя!
// Author -> hasMany(Book::class);
// Book -> hasMany(Rating::class);
$authors = Author::has('books.ratings')->get();
Есть несколько интересных типы полей, например:
$table->geometry('positions');
$table->ipAddress('visitor');
$table->macAddress('device');
$table->point('position');
$table->uuid('id');
Просмотреть все типы: https://laravel.com/docs/master/migrations#creating-column
Чтобы узнать параметры команды 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 — отладка
При создании миграций вы можете использовать типа поля ->timestamp() с параметром ->useCurrent(), который выставит дефолтным значением CURRENT_TIMESTAMP.
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
Используйте make:observer и метод creating() для автоматической установки поля user_id для залогиненного пользователя.
class PostObserver
{
/**
* Обрабатываем событие «создание» записи.
*
* @param \App\Post $post
* @return void
*/
public function creating(Post $post)
{
$post->user_id = auth()->id();
}
}
При использовании мягкого удаления (soft-deletes) вы можете восстановить одним запросом разом несколько записей.
Post::withTrashed()->where('author_id', 1)->restore();
В Eloquent отношении hasMany() вы можете отфильтровать записи, которые имеют X дочерних записей.
// Author -> hasMany(Book::class)
$authors = Author::has('books', '>', 5)->get();
При проверке загруженных изображений можно указать требуемые размеры:
'photo' => 'dimensions:max_width=4096,max_height=4096'
Продолжение: Советы по Laravel. Часть 2.
Автор: Povilas Korop
Перевод: Demiurge Ash