Я составил небольшой список советов, которые я нашел полезными при работе с Laravel.
1. при удалении(“установить значение null”)
Вы, вероятно, знаете об этом и использовали при удалении("каскад"); для внешних ключей при миграции Laravel, но знали ли вы о "установить значение null" ? Это позволяет сохранять модели при удалении связанной с ними модели. Примером этого может быть, если у вас есть комментарии, в которых есть пользователь, если пользователь будет удален, и вы хотите сохранить его комментарии, вы можете использовать OnDelete('установить значение null') . Это автоматически установит для вашего столбца идентификатор пользователя значение null, если пользователь будет удален, и вы можете обработать это на уровне представления данных, чтобы показать “Удаленный пользователь” в качестве автора или что-то подобное.
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('set null');
2. отбросить иностранный([]);
Долгое время я думал, что вы должны использовать полное имя ключа при откате ограничения внешнего ключа при миграции. Я также был сбит с толку, когда откат нескольких внешних ключей с использованием синтаксиса массива не сработал.
// doesn't work
$table->dropForeign('user_id');
// works
$table->dropForeign('posts_user_id_foreign');
// doesn't work
$table->dropForeign([
'posts_user_id_foreign',
'posts_type_id_foreign'
]);
Когда я прочитал документацию, чтобы понять, что происходит, я понял, что синтаксис массива на |/удалить внешний предназначен для удаления внешнего ключа с использованием сокращенного имени столбца.
$table->dropForeign(['user_id'])
Очень удобно! Но почему синтаксис массива? Что произойдет, если вы поместите туда несколько строк? Я просмотрел исходный код, чтобы выяснить это, так как это не было очевидно для меня из документации.
Вот капля иностранного:
/**
* Indicate that the given foreign key should be dropped.
*
* @param string|array $index
* @return \Illuminate\Support\Fluent
*/
public function dropForeign($index)
{
return $this->dropIndexCommand('dropForeign', 'foreign', $index);
}
Просто абстрактный вызов команды отбросить индекс , которая выглядит следующим образом:
/**
* Create a new drop index command on the blueprint.
*
* @param string $command
* @param string $type
* @param string|array $index
* @return \Illuminate\Support\Fluent
*/
protected function dropIndexCommand($command, $type, $index)
{
$columns = [];
// If the given "index" is actually an array of columns, the developer means
// to drop an index merely by specifying the columns involved without the
// conventional name, so we will build the index name from the columns.
if (is_array($index)) {
$index = $this->createIndexName($type, $columns = $index);
}
return $this->indexCommand($command, $columns, $index);
}
Поэтому, когда мы вызываем drop Foreign с массивом, он создает имя индекса, используя соответствующие столбцы. Поэтому, если бы у нас был составной индекс ключа, мы могли бы удалить его, используя синтаксис массива, и просто передать имена столбцов, вместо того, чтобы передавать полное имя индекса, как мы делаем с ограничением внешнего ключа.
3. Проверка модели
В Laravel существует множество различных способов проверки пользовательского ввода. Вы можете использовать объекты запроса, промежуточное программное обеспечение или даже проверять прямо в своих контроллерах. Недавно я определял правила проверки в красноречивых моделях. Затем вы можете подключаться к этим правилам всякий раз, когда вам нужно, например, в объекте запроса. Этот подход был вдохновлен фреймворком Elixir, Phoenix.
'required|string',
'phone_number' => 'string',
'user_id' => 'integer'
];
}
Вы можете использовать несколько наборов правил, если проверка создания и обновления отличается. Например, если ваш интерфейс отправляет только значения с изменениями для обновления, вы не хотите, чтобы все поля были помечены как обязательные.
'required|string',
'phone_number' => 'string',
'user_id' => 'integer'
];
/**
* Validation rules for update
*
* @var array
*/
public static $updateRules = [
'name' => 'string',
'phone_number' => 'string',
'user_id' => 'integer'
];
}
4. Миграция Данных
Иногда вы хотите поместить статическую информацию в базу данных для использования во всем приложении. Разрешения, названия стран или штатов, настройки по умолчанию – список можно продолжать. Если данные необходимо изменить или необходимо изменить версии, вы можете использовать миграции вместо сеялок. Я попробовал два подхода, и оба они хорошо работают.
Подход № 1 заключается в простом выполнении запросов, вставляющих, обновляющих или удаляющих данные при миграции. В этом сценарии я заполняю новую настройку значением по умолчанию.
key = 'emails';
// get values from constants to avoid magic strings
$values = [
'report_subject' => ReportEmailDefaults::SUBJECT,
'report_body' => ReportEmailDefaults::BODY
];
$setting->value = json_encode($values);
$team->settings()->save($setting);
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Setting::where('key', 'emails')
->where('settingable_type', 'team')
->delete();
}
}
Подход № 2 заключается в расширении класса миграции, чтобы упростить добавление/удаление данных. Я использовал этот подход при управлении разрешениями с помощью миграции. Это может выглядеть примерно так.
permissions;
}
final public function up(): void
{
$permissions = $this->getPermissions();
foreach($permissions as $permission)
{
Permission::create($permission);
}
}
final public function down(): void
{
Permission::whereIn('key', $this->getPermissions())->delete();
}
}
Всякий раз, когда вы хотите добавить разрешения, вам просто нужно создать новую миграцию, которая расширяет миграцию разрешений, и определить массив добавляемых ключей разрешений.
Это неполный пример, вы хотели бы создать способы обновления и удаления разрешений, но я надеюсь, что вы поняли идею.
5. Добавление атрибутов в запрос
Вы можете добавить атрибуты к объекту запроса Laravel с помощью промежуточного программного обеспечения. Один из сценариев, в котором это удобно, – это приложения с несколькими арендаторами, где вы хотите получить определенную команду или организацию и убедиться, что запрашивающий пользователь имеет к ней доступ, а также передать сущность, чтобы вам не приходилось искать ее несколько раз.
Вот как может выглядеть промежуточное программное обеспечение. Если вы копируете это дома, имейте в виду, что метод $user->cannot() является пользовательским вспомогательным методом Я обычно добавляю в свою пользовательскую модель. Я также использую систему разрешений на основе ролей, но вы можете использовать Laravel Gate и другие встроенные методы авторизации .
teamRepository = $teamRepository;
}
public function handle($request, Closure $next, ?string $guard = null): Closure
{
// Fetch the requesting user
/* @var $user \Acme\Authentication\User */
$user = Auth::guard('api')->user();
$slug = $request->teamSlug;
// Fetch the requested team
$team = $this->teamRepository->find($slug, 'slug');
// If no team is found, return a 404
if ( ! $team) {
abort(404);
}
// Make sure user has access
if($user->cannot(ViewTeam::key(), $team)) {
return response('Unauthorized', 401);
}
// Finally, add the team to the request
$request->attributes->add(['team' => $team]);
return $next($request);
}
}
Обязательно добавьте промежуточное программное обеспечение в группу промежуточного программного обеспечения маршрута в вашем Kernel.php файл, затем вы можете прикрепить промежуточное программное обеспечение к своим группам маршрутов
Route::prefix('/team/{teamSlug}')->middleware('team-lookup')->group(function () {
Route::get('/tasks', [TaskController:class, 'get']);
});
И в методе контроллера вы можете получить команду из объекта запроса.
public function get(Request $request): TaskResource
{
$team = $request->attributes->get('team');
$tasks = dispatch_now(new GetTeamTasks($team));
return TaskResource::collection($tasks);
}
6. Заказ моделей по удаленным многим-многим связанным элементам
Допустим, вы создаете систему, которая отслеживает производственные цепочки и управляет ими. При назначении продуктов машинам вы хотите получить список доступных машин, упорядоченных по продуктам, которые они поддерживают, с наиболее совместимыми в верхней части списка.
Возможно, у вас есть машинная сущность, принадлежащая к типу машины. Сущность типа машины имеет отношение “Многие ко многим” с продуктами.
Поэтому вам нужно выполнить подсчет и упорядочение на основе отношения “многие ко многим” с назначенным типом машины. Вы можете использовать с количеством с ограничениями для упорядочения результатов машины в зависимости от того, есть ли у отношения типа машины назначенные продукты, которые вы ищете.
$machines = $machines->withCount(['type' => function($query) use($product) {
$query->whereHas('products', function($query) use($product) {
$query->where('products.id', $product->id);
});
}])->orderBy('type_count', 'desc');
Независимо от того, есть ли у назначенного типа назначенные продукты, для параметра type_count будет установлено значение 0 или 1, по которому вы затем сможете упорядочить результаты.
Резюме
Я надеюсь, что вы нашли некоторые из этих советов полезными. Не стесняйтесь добавлять свои мысли, комментарии, критику или идеи ниже!
Сообщение 6 советов по Laravel появилось первым на Мэтт Делает Код .
Оригинал: “https://dev.to/mattnmoore/6-laravel-tips-4k2i”