# coding: utf-8

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 скрипт принимает, дополнительно, перечень действий, поэтому мы включим некоторые из наших первоначальных действий непосредственно в командную строку

Листинг 3.4. Создание контроллера Pages (Страницы).
  $ 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: Содержимое <code>config</code> директории примера приложения.

Рисунок 3.4: Содержимое config директории примера приложения.

Так как мы сгенерировали home и contact действия, routes файл уже имеет правила для каждого из них, что видно в Листинге 3.5.

Листинг 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.

Рисунок 3.5: Cырое home представление (/pages/home), сгенерированное Rails.

Блок 3.1. GET и т.д..

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 конвенции.)

Листинг 3.6. Контроллер Pages сделанный в Листинге 3.4.

app/controllers/pages_controller.rb
  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).

Листинг 3.7. Сгенерированное представление для страницы Home.

app/views/pages/home.html.erb
  <h1>Pages#home</h1>
  <p>Find me in app/views/pages/home.html.erb</p>

Представление для contact действия выглядит аналогично (Листинг 3.8).

Листинг 3.8. Сгенерированное представление для страницы Contact

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"
# coding: utf-8