Модель-вид-контроллер (MVC) — очень распространённый шаблон проектирования современных веб-приложений. Широкое использование и признание шаблона проектирования означает, что многие популярные фреймворки построены на основе этой архитектуры.
Laravel 4 — один из таких фреймворков, который использует шаблон проектирования MVC, чтобы аккуратно разделять между собой различные аспекты веб-приложения.
В этой статье мы рассмотрим, что именно представляет собой модель, каковы три важнейших компонента бизнес-логики, и как настроить свою первую модель в Laravel 4.
Что такое модель?
Так что же такое модель? Если мы собираемся построить всё приложение на моделях, сначала мы должны понять, что именно они из себя представляют.
Модель должна содержать всю бизнес-логику вашего приложения. Или, другими словами, то, как приложение взаимодействует с базой данных.
- Объекты реального мира, которые используются в вашем приложении
- То, как эти объекты взаимодействуют друг с другом
- Набор правил для доступа к этим объектам и для их обновления
Поэтому, например, PHPUsers
станет важным объектом в Cribbb, потому что это социальное приложение.
- Мы должны хранить информацию о наших пользователях, и поэтому нам нужна модель
PHPUser
и таблицаPHPUser
в базе данных. - Пользователям надо будут вводить имя, адрес электронной почты и пароль, а также другие детали профиля. Чтобы удостовериться, что они вводят правильно отформатированные данные, мы должны проверять их ввод.
- Пользователи смогут создавать сообщения. Пользователь может иметь много сообщений, и каждое сообщение должно принадлежать пользователю.
Это основные особенности работы моделей в приложениях MVC. По существу для каждой важной вещи в приложении, вероятно, потребуется модель. Вам, возможно, понадобится проверять данные, используемые в вашей модели, а так же здесь должна быть вся логика, отвечающая за взаимодействие моделей друг с другом.
Создание модели User
Проверка подлинности пользователя требуется почти в каждом современном веб-приложении. Вместо того чтобы заставлять вас писать свою собственную модель пользователя, в Laravel 4 уже есть модель пользователя прямо из коробки.
Если вы зайдете в каталог app/models, то найдете там файл User.php. Все ваши модели должны помещаться в этом каталоге и именоваться таким же образом. Например, в вашем приложении есть модель для сообщений, тогда файл модели будет называться app/models/Post.php.
Между прочим, вам не обязательно следовать этому правилу, есть способы его обойти, но я не представляю, зачем вам это может понадобиться.
Как бы то ни было, если вы откроете модель пользователя, вы увидите довольно базовый шаблон модели.
Анатомия модели Laravel
Как я уже говорил, каждая модель должна быть представлена в БД таблицей. Для взаимодействия с БД нам понадобится расширить модель с помощью PHPEloquent
. Eloquent — это реализация ActiveRecord, которая поставляется с Laravel.
Каждая модель расширяет PHPEloquent
и поэтому наследует все его методы для работы с БД:
class User extends Eloquent {}
Вы также заметите, что модель пользователя по умолчанию реализует два интерфейса:
implements UserInterface, RemindableInterface
Сегодня я не собираюсь описывать интерфейсы или запоминаемые (remindable) функции, которые встроены в модель пользователя Laravel, их мы рассмотрим более подробно в следующих уроках.
Следующее, что вы заметите, это защищенное свойство PHP$table
:
/**
* Таблица БД, используемая моделью.
*
* @var string
*/
protected $table = 'users';
Как вы могли догадаться, это просто объявление имени таблицы, к которой относится эта модель. По умолчанию вам не надо задавать это свойство, потому что Laravel следует мантре соглашения вместо настройки. В общем, это означает, что если вы назовете свою модель PHPUser
, то Laravel будет считать, что имя вашей таблицы PHPusers
. Задание свойства PHP$table
полезно, когда вы не хотите соблюдать это правило для названия таблицы.
Свойство PHP$hidden
позволяет скрыть определенные столбцы при возвращении экземпляра модели:
/**
* Атрибуты, исключенные из JSON-представления модели.
*
* @var array
*/
protected $hidden = array('password');
Это просто массив имен полей. Это полезно, когда вам надо вернуть информацию пользователя через JSON API, например. Вряд ли при этом вы захотите показать пароль пользователя.
Далее нам надо защититься от массового присвоения (mass assignment). Когда вы передаете массив данных в модель, данные автоматически массово назначаются соответствующим полям. Это удобно, потому что это многое упрощает, но в то же время представляет довольно серьезную проблему безопасности. Например, вам не нужно чтобы пользователи могли изменять их идентификаторы (id), так как они должны задаваться автоматически при создании пользователя и не должны изменяться никогда.
Для защиты от массового присвоения мы должны указать, какие столбцы могут массово назначаться. Чтобы это сделать, мы должны задать свойство PHP$fillable
.
protected $fillable = array('username', 'email');
Это гарантирует, что только эти поля могут массово назначаться.
Вы также можете задать свойство PHP$guarded
, которое предотвращает массовое назначение перечисленных столбцов. Например:
protected $guarded = array('id', 'password');
И, наконец, модель включает три простых метода для возврата конкретных элементов данных из неё:
/**
* Получить уникальный идентификатор пользователя.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Получить пароль пользователя.
*
* @return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Получить адрес e-mail для отправки напоминания о пароле.
*
* @return string
*/
public function getReminderEmail()
{
return $this->email;
}
Проверка данных в вашей модели
Все хорошие приложения в определенный момент требуют проверки данных. Пользователи склонны делать ошибки и вводить неверные данные, и поэтому вы должны контролировать, что только правильные данные могут быть введены в систему.
В Laravel 4 есть фантастический пакет Validation, который позволяет невероятно легко создавать и обеспечивать выполнение правил проверки данных.
Тем не менее, Laravel 4 не заставляет вас выносить проверки в ваши модели. Распространена плохая практика — помещать проверку в контроллере. Плоха она тем, что скорее всего вам придется повторить проверку в нескольких местах вашего приложения.
Намного лучшим местом для вашей проверки будет модель, потому что всё взаимодействие с БД должно происходить через модель, поэтому вам понадобится написать ваши правила только один раз.
Поскольку для Laravel 4 не важно, куда вы поместите вашу логику проверки, я собираюсь использовать превосходный пакет Ardent, чтобы все это обрабатывать. Ardent позволяет создавать самопроверяющие модели. Это означает, что ваши модели будут проверять себя всякий раз, когда вы взаимодействуете с ними, поэтому вам не придется писать логику проверки.
Установка Ardent через Composer
Ardent является Composer-пакетом, поэтому его можно установить, просто добавив в файл composer.json.
js{ "require": { "laravelbook/ardent": "dev-master" } }
Затем для обновления вашего проекта выполните:
shcomposer update
Проверка моделей с помощью Ardent
Для того чтобы использовать Ardent, сначала нужно изменить базовый класс модели User.
Наследование от Ardent
В файле User.php вам надо обновить две следующие строчки:
// Добавьте эту строчку
use LaravelBook\Ardent\Ardent;
// Обновите эту строчку
class User extends Ardent implements UserInterface, RemindableInterface {
Не волнуйтесь, все методы Eloquent по-прежнему доступны через Ardent, потому что Ardent напрямую совместим с PHPEloquent
.
Правила проверки
Следующее, что мы должны сделать, это создать набор правил проверки для каждого из полей модели.
/**
* Правила проверки Ardent
*/
public static $rules = array(
'username' => 'required|between:4,16',
'email' => 'required|email',
'password' => 'required|alpha_num|min:8|confirmed',
'password_confirmation' => 'required|alpha_num|min:8',
);
Ardent использует класс Validation для создания этих простых в использовании правил проверки. Правила проверки для вашей модели просто хранятся в качестве открытого статического массива. Как вы видите, в массиве каждое правило отделяется вертикальной чертой (|).
Полный список доступных правил проверки можно посмотреть в этом разделе документации.
Использование проверок Ardent
Как я упоминал в описании Ardent, все ваши модели будут «самопроверяющими». Это значит, что ваши модели будут автоматически отклонять ввод, который не удовлетворяет вашим правилам проверки, и вам ничего не нужно делать для этого.
Например, следующий код не сработает, потому что я не предоставил подтверждение пароля:
$user = new User;
$user->username = 'philipbrown';
$user->email = 'phil@ipbrown.com';
$user->password = 'deadgiveaway';
$user->save(); // вернёт false
$user = new User;
$user->username = 'philipbrown';
$user->email = 'phil@ipbrown.com';
$user->password = 'deadgiveaway';
$user->password_confirmation = 'deadgiveaway';
$user->save(); // вернёт true
Обратите внимание, вам не придется проверять все данные самостоятельно. Если проверка не пройдена, модель просто не будет сохранена.
Автоматическое удаление избыточных данных
На самом деле нам не нужно сохранять данные password_confirmation, потому что они используются только для проверки. Чтобы указать Ardent просто удалять избыточные данные, такие как поля подтверждения, надо добавить в модель PHPUser
следующую строчку:
public $autoPurgeRedundantAttributes = true;
Пример проверки данных на практике
Для быстрой настройки примера для всего описанного, мы можем создать новый маршрут, который покажет нам это вживую.
Откройте app/routes.php и скопируйте в него следующий код:
Route::get('/user', function()
{
$user = new User;
$user->username = 'philipbrown';
$user->email = 'phil@ipbrown.com';
$user->password = 'deadgiveaway';
$user->password_confirmation = 'deadgiveaway';
var_dump($user->save());
});
Это просто создаст новый путь, по которому вы можете обратиться через браузер. Когда вы переходите в /user, Laravel автоматически создает нового пользователя и пытается сохранить его в БД. Если пользователь сохранится корректно, вы увидите на экране boolean true.
Сохраните routes.php и выполните в терминале следующую команду для быстрой настройки сервера:
shphp artisan serve
Теперь зайдите на localhost:8000/user, чтобы увидеть вашу проверку в действии.
Это было очень быстрое введение в проверку ваших моделей в Laravel 4. В ближайшее время я напишу гораздо более глубокую статью о специфических деталях проверки данных.
Отношения моделей Laravel
Третья и последняя характеристика модели — это то, что она содержит информацию, описывающую взаимодействие бизнес-объектов друг с другом.
Описать отношения двух моделей так же просто, как создать новый метод класса.
Добавьте следующий метод в вашу модель User.php:
/**
* Отношение с сообщениями
*/
public function posts()
{
return $this->hasMany('Post');
}
Этот крайне простой метод — единственное, что вам нужно написать, для того, чтобы сказать, что «пользователь имеет много сообщений».
Конечно, теперь вам надо создать модель сообщения, для того чтобы это заработало. Я не буду описывать создание миграции (migration) и модели сообщения. Вместо этого вернитесь к уроку «Миграции в Laravel 4». Я просто создам столбцы body и user_id для моей модели сообщения. Вот команда миграции, которую я выполнил:
shphp artisan generate:migration create_posts_table --fields="body:text, user_id:integer"
Таким образом, ваша базовая модель сообщения должна выглядеть так:
class Post extends Eloquent {
protected $fillable = array('body');
public function user()
{
return $this->belongsTo('User');
}
}
Обратите внимание, как я задал обратное отношение в методе PHPuser()
. Это значит, что каждый пост принадлежит пользователю.
Далее создайте новый тестовый маршрут в app/routes.php и вставьте следующее:
// Создание нового сообщения
$post = new Post(array('body' => 'Yada yada yada'));
// Выбор пользователя с ID 1
$user = User::find(1);
// Сохранение сообщения
$user->posts()->save($post);
Теперь, если вы посмотрите в таблицу сообщений в вашей БД, вы увидите, что сообщение сохранено и полю user_id автоматически присвоен идентификатор пользователя (1).
Это был очень быстрый обзор создания отношений в ваших моделях Laravel. Повторюсь, я расскажу о каждой из этих областей подробнее, когда мы добавим несколько более сложных вещей в Cribbb. Больше информации об отношениях моделей Laravel можно найти в документации.
Заключение
Это был быстрый обзор создания моделей Laravel. Надеюсь, у вас появилось чёткое понимание трёх важных аспектов бизнес-логики, которые должны быть в ваших моделях.
Как я уже упоминал пару раз в этой статье, в следующих уроках я гораздо глубже погружусь в тонкости работы моделей в веб-приложениях.
Внимательные читатели уже заметили, что я не следую строго концепции Test Driven Development. Но не волнуйтесь, на следующей неделе я опишу создание тестов модели используя PHPUnit.
Эта серия статей о создании полностью открытого (Open Source) приложения Cribbb. Все уроки будут размещены бесплатно в интернете, а весь код доступен на GitHub.
Возвращайтесь в следующий понедельник, рассмотрим написание автоматических тестов для ваших моделей!
Следующая статься в этой серии — «Приступаем к тестированию моделей Laravel 4».