Рубрики
Uncategorized

6 Советов Laravel

6 полезных советов по работе с Laravel. Помечено как веб-разработчик, php, laravel, новички.

Я составил небольшой список советов, которые я нашел полезными при работе с 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”