Поэтапная разработка сайта на Laravel 4: урок №4

Доброго времени суток 🙂

Настало время для четвертого урока, и в нем мы реализуем следующее:

  • Создадим модель для планет
  • Реализуем форму добавления планет в базу (с валидацией и сообщениями об ошибках)
  • Выведем список последних планет на главной странице

Итак, начнем с создания контроллера, который будет отвечать за обработку и вывод всех страниц, связанных с планетам. Назовем его  PlanetsController и поместим в app/controllers/PlanetsController.php :

Важно, чтобы имя файла совпадало с именем класса, который в этом файле содержится, чтобы автозагрузчик мог без проблем этот класс подключить по мере необходимости.

И сразу можем создать маршрут для этого контроллера в  app/routes.php :

Если кто не до конца усвоил материал второго урока, напомню, что эта запись создаст маршруты для всех методов указанного контроллера, причем маршруты эти будут начинаться с  /planets . Возможно плюс, а возможно и минус этого подхода в том, что маршруты будут генерироваться при каждом запросе, а не единожды. Плюс в том, что нам уже не придется трогать файл  routes.php для новых маршрутов конкретно этого контроллера: по мере добавления новых методов в него маршруты также появятся.

Первым делом предлагаю начать с вывода формы для добавления планеты, которая будет отображаться по URL’у /planets/add . Для этого нужно добавить один незамысловатый метод в контроллер:

Этот метод просто вернет пользователю шаблон  app/views/planets/add.blade.php , который нам и предстоит сейчас создать. Суть этого шаблона заключается в простой генерации формы со всеми необходимы полями для добавления новой планеты.

Как я уже упоминал ранее, используемая в Laravel Eloquent ORM нигде не хранит структуру базы данных и, соответственно, моделей. Поэтому в Laravel, по крайней мере «из коробки», не существует автоматической генерации форм для модели. То есть все поля нужно прописывать «вручную». Но тут на помощь нам придет так называемый FormBuilder, доступный через фасад Form. Он содержит многочисленные методы для генерации различных элементов форм, а также имеет поддержку так называемого model-биндинга, то есть «умного» отображения моделей, о чем я расскажу детальнее, когда мы дойдем до редактирования существующих планет.

Итак, давайте создадим шаблон для создания планет в файле app/views/planets/add.blade.php . Начнем с «каркаса»:

Как можно видеть, форма, пока пустая, создается вызовами  Form::open(...) и  Form::close() . С последним, думаю, все понятно: он просто генерирует закрывающий тэг  </form> . А вот  Form::open(...) рассмотрим подробнее.

Синтаксис этой команды на самом деле прост: в передаваемом массиве мы передаем «настройки» формы. Есть некоторые «зарезервированные» ключи у этого массива, как например  url — он задает  action формы, то есть адрес (см. примечание), куда будет отправлена форма. Остальные же элементы массива просто определяют дополнительные атрибуты тэга  <form ...> . В нашем случае:

  • 'method' => 'post' добавляет атрибут  method , указывающий, что форма должна быть отправлена методом POST
  • 'role' => 'form'  и  'class' => 'form-horizontal' являются чисто украшательными, так мы создаем форму, используя Bootstrap.

Примечание: в данном случае адрес указывается не напрямую  /planets/add , а посредством вспомогательной функции action , которая генерирует этот путь исходя из переданного ей контроллера и метода. В этом есть смысл, если вдруг в определении маршрута вы решите заменить planets  на что-то другое, при этом код создания этой формы менять не придется.

Теперь, чтобы это заработало, нужно создать, пока пустой, метод postAdd  в нашем контроллере, иначе функция action  сгенерирует ошибку:

Опять же, для тех, кто вдруг не полностью усвоил второй урок, напомню: мы имеем дело с двумя разными маршрутами, хоть и имеющих одинаковый URL /planets/add . При запросе адреса http://sbshare.localhost:8000/planets/add  из броузера (это GET  запрос), будет выполнен метод getAdd , в то время как форма будет отправлена на такой же адрес, но уже методом POST , и, следовательно, отрабатывать будет метод postAdd  контроллера.

Теперь я предлагаю сделать следующее: саму форму мы вынесем в отдельный под-шаблон form.blade.php , а в этот лишь добавим кнопку submit  (отправку формы) и инклюд самой формы. Таким образом часть шаблона add.blade.php будет такой:

Обратить внимание стоит на инклюд под-шаблона: @include('planets/form') , который будет содержать саму форму. Делаю я так потому, что для редактирования планеты у нас будет абсолютно идентичная форма. Разница лишь в открывающей инструкции — в случае с редактированием форма будет открываться посредством  Form::model(...) — что позволяет «привязать» модель планеты к форме. Но об этом позже. Сейчас давайте напишем код для генерации само формы в файле app/view/planets/form.blade.php .

Как я уже говорил, для генерации различных элементов форм у фасада Form  есть множество методов. Например, для генерации text-input ‘а в простейшей форме может использоваться такая запись:

Результатом этого вызова будет такой input :

Как и другие методы фасада, метод text может принимать дополнительные параметры:

  • второй необязательный параметр указывает значение value это поля
  • третий необязательный аргумент — это массив, описывающий дополнительные атрибуты input’а. В большинства случае он используется для указания требуемого CSS-класса input’а

Например, вызов Form::text('fieldName', 'some-value', array('class' => 'my-input-class'))  сгенерирует такой input :