Урок 23. Введение в области применения (scope) Laravel


Определение области применения (действия, scope) - одна из сверхспособностей, которую Eloquent предоставляет разработчикам при запросе модели. Области позволяют разработчикам добавлять ограничения к запросам для данной модели. Все уроки по Laravel.



Использование области видимости Eloquent помогает нам следовать принципам DRY при написании запросов для наших моделей. Когда конкретный запрос повторяется снова и снова во многих местах нашей бизнес-логики, его следует абстрагировать в область видимости.

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

Локально (local scope)

/**
* Область запроса, включающая только популярных пользователей.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopePopular($query)
{
	return $query->where('votes', '>', 100);
}
Приведенный выше блок кода показывает пример локальной области, область - это просто метод в вашем классе модели, который начинается со слова “scope”, а затем имени области и может использоваться с вашей моделью.

scopePopular — Model::popular()->get();
scopeTeacher — Model::teacher()->get();
scopeMortages — Model::mortages()->get();
scopeSubscribers — Model::subscribers()->get();
Как видно из блока кода, метод области видимости должен быть объявлен с параметром, условно называемым $query, но может быть изменен на любое другое правильно сформированное имя переменной. Этот параметр $query является экземпляром Eloquent builder, который используется в основном во всех наших запросах модели eloquent. Есть и другие методы, подобные области видимости, которые доступны для использования при запросе моделей в приложениях Laravel: where, orWhere, with, all, paginate, distinct, onlyTrashed, withTrashed, withoutTrashed, create Глобально

/**
* Метод "загрузки" модели.
*
* @return void
*/
protected static function booted()
{
	static::addGlobalScope('age', function (Builder $builder) {
	$builder->where('age', '>', 200);
});
}
Как видно выше, глобальные области добавляются немного иначе, чем локальная область, они добавляются в статическом загружаемом методе модели с использованием статического метода addGlobalScope, который получает два аргумента, имя области и закрытие. Закрытие области, как и в локальной области, объявляет параметр $builder (локальная область использует $query), и эти переменные могут быть переименованы в соответствии с выбором разработчика. Чтобы выполнять запросы без объявленной глобальной области, статический метод без глобальной области вызывается вместе с моделью и указывается имя области:

Model::withoutGlobalScope($globalScopeName)->get();
//замените переменную $globalScopeName именем области
Разница между локальным и глобальным

Локальные области применяются пользователем, используются при построении запроса, в то время как глобальные области применяются ко всем запросам в этой модели. Примером глобальной области, используемой Laravel, является извлечение не удаленных записей (при использовании мягкого удаления - soft deletes) при запросе модели, а для извлечения записей с удаленными записями используется локальная область с удаленными записями

Динамическая локальная область действия

Эти типы областей являются локальными областями, которые получают аргумент от разработчика при использовании области, по умолчанию методы, подобные области, такие как where, или где считаются динамическими, и для создания динамической области создайте локальную область, которая имеет 2, 3 или более параметров в соответствии с вашими потребностями:

/**
* Область запроса должна включать только пользователей определенного типа.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param mixed $type
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeOfType($query, $type)
{
	return $query->where('type', $type);
}
Параметр $type должен быть предоставлен разработчиком при использовании области OfType, иначе будет выдана ошибка.

Примеры использования

  • Роли пользователей. Если вы используете столбец роли в модели пользователя, чтобы определить, является ли пользователь учителем или учеником:

        //local scope
        public function scopeTeachers($query)
        {
            return $query->where('role', 'teacher');
        }    public function scopeStudents($query)
        {
            return $query->where('role', 'student');
        }
    или
        //dynamic local  scope    
        public function scopeType($query,$userType)
        {
            return $query->where('role', $userType);
        }Model::teachers()->get(); or Model::type('teacher')->get();
    Model::students()->get(); or Model::type('student')->get();
    
  • Публикации. Публикации в вашем приложении имеют столбец статуса, чтобы определить, опубликована публикация или нет, это было бы идеальным сценарием для использования глобальной области для фильтрации публикуемых сообщений.

    protected static function booted()
    {
    	static::addGlobalScope('status', function (Builder $builder){
    		$builder->where('status',1);
    	});
    }
    
    При этом вызов функции Model::all() будет извлекать только записи, имеющие значение 1 в столбце статус.
Существует множество возможных сценариев, в которых пригодятся области видимости, как локальные, так и глобальные, и их использование поможет сохранить код ваших контроллеров чистым.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, уроки по Laravel, laravel




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Урок 14. Метод public static void main
Новый проект: парсим docx и пишем в xlsx
Excel и автопреобразование в дату