3.1.2 Статические страницы с Rails
Возможность возвращать (показывать) статические HTML файлы это хорошо, но это не особенно полезно для создания динамических веб-приложений. В этом разделе мы сделаем первый шаг на пути создания динамических страниц, создав несколько Rails действий, которые являются более мощным средством для определения URL(-ов), нежели статические файлы. 5 Rails действия взаимосвязаны внутри контроллера (Controller) (C в MVC из Раздела 1.2.6), который содержит ряд actions (действий), связанных общей целью. Мы получили представление о контроллерах в Главе 2, и придем к еще более глубокому пониманию их когда изучим REST архитектуру более полно (начиная с Главы 6); в сущности, контроллер это контейнер для группы (возможно, динамических) веб-страниц .
Для начала вспомним из Раздела 1.3.5 что при использовании Git, хорошо бы делать нашу работу в ветке (ответвлении) (branch) с отдельной темой, а не в мастер ветке. Если вы используете Git для управления версиями, вы должны выполнить следующую команду:
$ git checkout -b static-pages
Rails поставляется со скриптом для создания контроллеров называемым generate
; имя контроллера это все, что ему (скрипту) нужно для его магической работы. Так как мы делаем этот контроллер для обработки (в основном) статичных страниц, мы просто назовем его Pages контроллер, и запланируем сделать actions (действия) для Home, Contact и About страниц. Generate
скрипт принимает, дополнительно, перечень действий, поэтому мы включим некоторые из наших первоначальных действий непосредственно в командную строку
$ rails generate controller Pages home contact create app/controllers/pages_controller.rb route get "pages/contact" route get "pages/home" invoke erb create app/views/pages create app/views/pages/home.html.erb create app/views/pages/contact.html.erb invoke rspec create spec/controllers/pages_controller_spec.rb create spec/views/pages create spec/views/pages/home.html.erb_spec.rb create spec/views/pages/contact.html.erb_spec.rb invoke helper create app/helpers/pages_helper.rb invoke rspec
(Отметим, что из-за установки RSpec посредством rails generate rspec:install
, генерация контроллера автоматически создает RSpec test файлы в spec/
директории). Здесь я намеренно “забыл” about
страницу, так что мы сможем увидеть, как добавить ее вручную (Раздел 3.2).
Pages контроллер, сгенерированный в Листинге 3.4 автоматически обновляет routes файл, из каталога config/routes.rb
, который Rails использует для определения соответствий между URL и веб страницами. Tак как это наше первое знакомство с config
директорией, полезно взглянуть на нее (Рис. 3.4). Сonfig
— директория где Rails хранит файлы, необходимые для конфигурации приложения — отсюда и название.

Рисунок 3.4: Содержимое config
директории примера приложения.
Так как мы сгенерировали home
и contact
действия, routes файл уже имеет правила для каждого из них, что видно в Листинге 3.5.
home
и contact
действий контроллера Pages.config/routes.rb
SampleApp::Application.routes.draw do get "pages/home" get "pages/contact" . . . end
Здесь правило
get "pages/home"
направляет запрос URL /pages/home в home
действие Pages контроллера. Более того, используя get
мы приговариваем маршрут отвечать на GET запрос, который является одним из фундаментальных HTTP глаголов поддерживаемых протоколом передачи гипертекста (Блок 3.1). В нашем случае это значит, что когда мы сгенерировали home
действие внутри контроллера Pages мы автоматически получили страницу по адресу /pages/home. Чтобы увидеть результаты, убейте сервер, нажав Ctrl-C, запустите rails server
, а затем перейдите на /pages/home (Рис. 3.5).

Рисунок 3.5: Cырое home представление (/pages/home), сгенерированное Rails.
HyperText Transfer Protocol ("протокол передачи гипертекста") (HTTP) определяет четыре основных операции, соответствующие четырем глаголам GET (получить), POST (отправить), PUT (поместить), и DELETE (удалить). Они относятся к операциям между клиентским компьютером (как правило, работает веб-браузер, например Firefox или Safari) и сервером (как правило, работает веб-сервер, такой как Apache или Nginx). (Важно понимать, что при разработке Rails приложения на локальном компьютере, клиент и сервер на одной физической машине, но в целом они разные.) Акцент на глаголы HTTP является типичным для фреймворков (веб-платформ) (включая Rails), находящихся под влиянием REST архитектуры, (ее основы рассматриваются в Главе 2 и более подробно в Главе 8).
GET является самой распространенной операцией HTTP, используемой для чтения данных в Интернете; это просто означает "получить страницу", и каждый раз, когда вы посещаете сайт, такой как google.com или craigslist.org браузер передает запрос GET.
POST это следующая наиболее распространенная операция, это запрос, передаваемый вашим браузером при предоставлении (заполнении) формы. В Rails приложениях, POST запросы обычно используются для создания вещи (хотя HTTP позволяет POST также выполнять обновления), например, запрос POST отправляется, когда вы представляете регистрационную форму, создаете нового пользователя на удаленном сайте.
Два других глагола, PUT и DELETE, предназначены для обновления и уничтожения вещей на удаленном сервере. Эти запросы встречаются реже, чем GET и POST поскольку браузеры не в состоянии отправить их в естественном виде.
Чтобы понять, откуда появилась эта страница, для начала посмотрите на контроллер Pages в текстовом редакторе, вы должны увидеть что-то вроде Листинга 3.6. (Вы можете отметить, что, в отличие от демо контроллеров Users и Microposts из Главы 2, контроллер Pages не следует REST конвенции.)
class PagesController < ApplicationController def home end def contact end end
Мы видим здесь, что pages_controller.rb
определяет класс называемый PagesController
. Классы это просто удобный способ организовать функции (также называемые методами), такие как home
и contact
действия, которые определяются с помощью ключевого слова def
. Угловая скобка <
указывает, что PagesController
наследует от Rails класса ApplicationController
; как мы увидим через мгновение, это означает, что наши страницы оснащены большим количеством Rails-определенных функций. (Мы узнаем больше об этих двух классах и наследовании в Разделе 4.4.)
В случае с контроллером Pages, оба его метода изначально пусты:
def home end def contact end
В переводе на простой Ruby, эти методы просто ничего не делают. В Rails, ситуация иная; PagesController
это класс Ruby, а потому, он наследует от ApplicationController
поведение его методов, специфичное для Rails: при посещении URL /pages/home, Rails смотрит в контроллер Pages и выполняет код в home
а затем визуализирует представление (view) (V в MVC из Раздела 1.2.6) соответствующее действию. В данном случае, home
действие пустое, так что все посещения /pages/home просто визуализируют представления. Итак, как же выглядит представление, и как мы можем его найти?
Если вы еще раз посмотрите на Листинг 3.4, вы можете найти, соответствие между действиями и представлениями: действие, такое как home
имеет соответствующее представление home.html.erb
. Мы узнаем в Разделе 3.3 что означает .erb
часть расширения; .html
часть расширения подсказывает, что представление, в основном, выглядит как HTML (Листинг 3.7).
app/views/pages/home.html.erb
<h1>Pages#home</h1> <p>Find me in app/views/pages/home.html.erb</p>
Представление для contact
действия выглядит аналогично (Листинг 3.8).
app/views/pages/contact.html.erb
<h1>Pages#contact</h1> <p>Find me in app/views/pages/contact.html.erb</p>
Оба эти представления — лишь заглушки: у них есть заголовок (внутри h1
тега) и абзац (p
тег) с указанием полного пути к соответствующему файлу. Мы добавим немного (очень немного) динамического контента, начиная с Раздела 3.3, но пока они статичны, эти представления подчеркивают важный момент: Rails представления могут просто содержать статический HTML. Что касается браузера, то, чистые HTML файлы из Раздела 3.1.1 и контроллер / действие метод доставки страниц неразличимы: все, что видит браузер, это HTML.
В оставшейся части этой главы, мы сначала добавим about
действие, которое мы “забыли” в Разделе 3.1.2, добавим очень небольшое количество динамического содержимого, а затем сделаем первые шаги в сторону дизайна страниц с CSS. Прежде чем двигаться дальше, если вы используете Git , хорошая идея, добавить сейчас файлы для контроллера Pages в репозитарий:
$ git add . $ git commit -m "Added a Pages controller"