Опубликован: 27.01.2016 | Доступ: свободный | Студентов: 914 / 58 | Длительность: 23:07:00
Лекция 3:

В основном статические страницы

Статические страницы

В этом разделе мы предпримем первые шаги в направлении создания динамических страниц создав набор Rails actions (действий) и views(представлений) содержащих (пока) только статический HTML.5Наш метод создания статических страниц является, вероятно, самым простым, но это не единственный путь. Оптимальный метод действительно зависит от ваших потребностей; если вы ожидаете большое количество статических страниц, использование контроллера StaticPages может стать довольно громоздким, но в нашем демонстрационном приложении нам понадобятся лишь несколько. Rails действия объединены внутри контроллеров (C в MVC из Раздела 1.2.6), которые содержат наборы действий связанных общим назначением. Мы получили некоторое представление о контроллерах в Главе 2 и придем к их более глубокому пониманию когда начнем использовать REST архитектуру более плотно (начиная с Главы 6); по сути, контроллер это контейнер для группы (возможно динамических) веб страниц.

Для того чтобы сориентироваться, полезно будет вспомнить структуру директорий Rails из Раздела 1.2.3 ( рис. 1.2). В этом разделе мы в основном будем работать в app/controllers и app/views директориях. (В Разделе 3.2 мы даже добавим свою собственную директорию.) А сейчас я советую вам открыть пример приложения в вашем текстовом редакторе (или IDE) (Box 3.1).

___________________________________________

Блок 3.1.Открытие проекта

Полезно иметь возможность открывать весь Rails-проект в вашем текстовом редакторе или IDE. К сожалению, способ сделать это зависит от системы, но в большинстве случаев вы можете открыть текущую директорию приложения (которая представлена в Unix точкой "."), используя команду командной строки для вашего редактора:

  $ cd ~/rails_projects/sample_app
  $ <название редактора> .

Например, для того чтобы открыть пример приложения в Sublime Text, вы наберете

  $ subl .

Для Vim это будет

 $ vim .

(где vim может быть gvim или mvim в зависимости от того какой именно Vim вы используете).

___________________________________________

Для того чтобы начать со статическими страницами, вспомните из Раздела 1.3.5 что, при использовании Git, хорошей практикой является делать нашу работу в отдельной, а не в master ветке. Если вы используете Git для контроля версий, вам следует выполнить следующую команду:

$ git checkout -b static-pages

Rails поставляется со скриптом для создания контроллеров называемым generate; имя контроллера это все, что ему (скрипту) нужно для его магической работы. Поскольку мы будем делать контроллер для обработки статических страниц, мы назовем его StaticPages. Мы также планируем сделать действия для страниц Home, Help и About. Скрипт generate принимает в качестве необязательного параметра список действий, так что мы включим два из начальных действий непостредственно в команду вызова скрипта (Листинг 3.4).

$ rails generate controller StaticPages home help --no-test-framework
      create  app/controllers/static_pages_controller.rb
       route  get "static_pages/help"
       route  get "static_pages/home"
      invoke  erb
      create    app/views/static_pages
      create    app/views/static_pages/home.html.erb
      create    app/views/static_pages/help.html.erb
      invoke  helper
      create    app/helpers/static_pages_helper.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/static_pages.js.coffee
      invoke    scss
      create      app/assets/stylesheets/static_pages.css.scss
Листинг 3.4. Генерация контроллера StaticPages.

Обратите внимание на опцию --no-test-framework используемую для подавления генерации дефолтных RSpec тестов, которые мы не планируем использовать. Вместо этого мы создадим тесты вручную в Разделе 3.2. Мы также намеренно не включили about действие в аргументы команды из Листинга 3.4 поэтому мы сможем увидеть как добавить его используя разработку через тестирование, или TDD (Раздел 3.2).

В Листинге 3.4, обратите внимание на то, что мы передали имя контроллера в так называемом CamelCase, что привело к созданию файла контроллера, название которого написано в snake_case, таким образом контроллер названный StaticPages привел к файлу названному static_pages_controller.rb. Это просто соглашение и, фактически, использование snake_case в командной строке допустимо: команда

$ rails generate controller static_pages ...

тоже сгенерирует контроллер с названием static_pages_controller.rb. Поскольку Ruby использует CamelCase для имен классов (Раздел 4.4), при упоминании контроллеров я предпочитаю использовать их названия в CamelCase, но это дело вкуса. (Поскольку Рубишные названия файлов обычно используют snake_case, Rails генератор конвертирует CamelCase в snake_case с помощью метода underscore.)

Кстати, на случай если вы когда-либо сделаете ошибку при генерации кода, вам пригодятся знания о том как обратить процесс. См. в Блоке 3.2 несколько техник переделывания в Rails.

___________________________________________

Блок 3.2. Переделки

Даже если вы очень осторожны, все же некоторые вещи иногда могут пойти не так при разработке Rails приложений. К счастью, в Rails есть несколько возможностей которые могут помочь вам откатить изменения.

Одним возможным сценарием является желание откатить генерацию кода связанное с необходимостью изменить название контроллера. При генерации контроллера, Rails создает гораздо большее количество файлов чем сам файл контроллера (как видно из Листинга 3.4). Откат генерации подразумевает не только удаление основного, но и всех сгенерированных вспомогательных файлов. (Фактически мы также хотим отменить все автоматические правки сделанные в файле routes.rb.) В Rails, это может быть осуществлено с помощью rails destroy. В частности, эти две команды отменяют друг друга:

  $ rails generate controller FooBars baz quux
  $ rails destroy  controller FooBars baz quux

Аналогично, в Главе 6 мы будем генерировать модель следующим образом:

$ rails generate model Foo bar:string baz:integer

Это действие может быть отменено с помощью

$ rails destroy model Foo

(В данном случае, оказывается, мы можем опустить остальные аргументы командной строки. Посмотрим, сможете ли вы понять почему по окончании Главы 6.)

Другая техника, связанная с моделями позволяет откатывать миграции, которые мы видели вкратце в Главе 2 и с которыми мы более подробно познакомимся в Главе 6. Миграции изменяют состояние базы данных с помощью

$ rake db:migrate

Мы можем откатить один шаг миграции с помощью

$ rake db:rollback

Для того чтобы откатить к самому началу (все миграции), мы можем использовать

$ rake db:migrate VERSION=0

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

С этими техниками на руках мы хорошо упакованы для того чтобы справиться с неизбежными при разработке казусами.

___________________________________________

Генерация контроллера StaticPages в Листинге 3.4 автоматически обновляет routes файл, из каталога config/routes.rb, который Rails использует для определения соответствий между URL и веб страницами. Tак как это наше первое знакомство с config директорией, полезно взглянуть на нее ( рис. 3.1). Сonfigдиректория где Rails хранит файлы, необходимые для конфигурации приложения — отсюда и название.

Содержимое config директории примера приложения.

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

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

SampleApp::Application.routes.draw do
  get "static_pages/home"
  get "static_pages/help"
  .
  .
  .
end
Листинг 3.5. Маршруты для home и help действий контроллера StaticPages. config/routes.rb

Здесь правило

get "static_pages/home"

направляет запрос для URL /static_pages/home в home действие контроллера StaticPages. Более того, используя get мы приговариваем маршрут отвечать на GET запрос, который является одним из основных HTTP глаголов поддерживаемых протоколом передачи гипертекста (Блок 3.3). В нашем случае это значит, что когда мы сгенерировали home действие внутри контроллера StaticPages мы автоматически получили страницу по адресу /static_pages/home. Чтобы увидеть результаты, убейте сервер, нажав Ctrl-C, запустите rails server, а затем перейдите на /static_pages/home ( рис. 3.2).

Cырое home представление (/static_pages/home).

Рис. 3.2. Cырое home представление (/static_pages/home).

___________________________________________

Блок 3.3. GET, et cet.

Hyper Text Transfer Protocol ("протокол передачи гипертекста") (HTTP) определяет четыре основных операции, cответствующие четырем глаголам GET (получить), POST (отправить), PATCH (править) и DELETE (удалить). Они относятся к операциям между клиентским компьютером (как правило, работает веб-браузер, например Firefox или Safari) и сервером (как правило, работает веб-сервер, такой как Apache или Nginx). (Важно понимать, что при разработке Rails приложения на локальном компьютере, клиент и сервер на одной физической машине, но в целом они разные.) Акцент на глаголы HTTP является типичным для фреймворков (веб-платформ) (включая Rails), находящихся под влиянием REST архитектуры, (ее основы рассматриваются в Главе 2 и более подробно в Главе 7.

GET является самой распространенной операцией HTTP, используемой для чтения данных в Интернете; это просто означает "получить страницу", и каждый раз, когда вы посещаете сайт, такой как google.com или wikipedia.org , ваш браузер передает запрос GET. POST это следующая наиболее распространенная операция, это запрос, передаваемый вашим браузером при предоставлении (заполнении) формы. В Rails приложениях, POST запросы обычно используются для создания вещи (хотя HTTP позволяет выполнять обновления и через POST ), например, запрос POST отправляется, когда вы отправляете заполненную регистрационную форму создающую нового пользователя на удаленном сайте. Два других глагола, PATCH и DELETE, предназначены для обновления и уничтожения вещей на удаленном сервере. Эти запросы встречаются реже, чем GET и POST поскольку браузеры не в состоянии отправить их в естественном виде, но некоторые фреймворки (включая Ruby on Rails) могут делать вид что браузеры отправляют такой запрос.

Кстати, предыдущие версии Rails использовали PUT вместо PATCH и Rails 4.0 все еще поддерживает такой подход, но PATCH лучше соответствует семантике HTTP и является предпочтительным для новых приложений.

___________________________________________

Чтобы понять, откуда появилась эта страница, для начала посмотрите на контроллер StaticPages в текстовом редакторе, вы должны увидеть что-то вроде Листинга 3.6. Вы можете отметить, что, в отличие от демо контроллеров Users и Microposts из Главы 2, контроллер StaticPages не использует стандартные REST действия. И это нормально для набора статических страниц: REST архитектура — не панацея для всех проблем.

class StaticPagesController < ApplicationController

  def home
  end

  def help
  end
end
Листинг 3.6. StaticPages контроллер созданный Листингом 3.4. app/controllers/static_pages_controller.rb

Здесь мы видим что static_pages_controller.rb определяет class называемый StaticPagesController. Классы это всего лишь удобный способ организации функций (также называемых методами) таких как home и help действия, определяемых с помощью ключевого слова def. Угловая скобка < указывает на то, что StaticPagesController наследует от Rails класса ApplicationController; как мы увидим через мгновение, это означает, что наши страницы оснащены большим количеством Rails-специфичных функций. (Мы узнаем больше об этих двух классах и наследовании в Разделе 4.4.)

В случае со StaticPages контроллером, оба его метода изначально пусты:

def home
end

def help
end

В переводе на простой Ruby, эти методы просто ничего не делают. В Rails, ситуация иная; StaticPagesController это класс Ruby, но благодаря тому, что он наследует от ApplicationController поведение его методов специфично для Rails: при посещении URL /static_pages/home, Rails смотрит в контроллер StaticPages и выполняет код в home действии, а затем рендерит view (представление) (V в MVC из Раздела 1.2.6) соответствующее данному действию. В данном случае home действие пустое, поэтому единственное что происходит при посещении /static_pages/home - рендеринг (отображение) представления. Итак, как же выглядит представление, и как мы можем его найти?

Если вы еще раз посмотрите на вывод в Листинге 3.4, вы можете найти соответствие между действиями и представлениями: действие, такое как home имеет соответствующее представление home.html.erb. Мы узнаем в Разделе 3.3, что означает .erb часть расширения; .html часть расширения подсказывает, что представление, в основном, выглядит как HTML (Листинг 3.7).

<h1>StaticPages#home</h1>
<p>Find me in app/views/static_pages/home.html.erb</p>
Листинг 3.7. Сгенерированное представление для Home страницы. app/views/static_pages/home.html.erb

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

<h1>StaticPages#help</h1>
<p>Find me in app/views/static_pages/help.html.erb</p>
Листинг 3.8. Сгенерированное представление для страницы Help. app/views/static_pages/help.html.erb

Оба эти представления — лишь заглушки: у них есть заголовок (внутри h1 тега) и абзац (p тег) с указанием полного пути к соответствующему файлу. Мы добавим немного (очень немного) динамического контента, начиная с Раздела 3.3, но пока они статичны, эти представления подчеркивают важный момент: Rails представления могут просто содержать статический HTML.

В оставшейся части этой главы мы добавим немного собственного контента в Home и Help страницы, а затем добавим About страницу которую мы пропустили в Разделе 3.1. Затем добавим очень небольшое количество динамического содержимого заменив статичный тайтл на тайтл, меняющийся в зависимости от страницы.

Прежде чем двинуться дальше, если вы используете Git, хорошей идеей будет добавление файлов для StaticPages контроллера в репозиторий:

$ git add .
$ git commit -m "Add a StaticPages controller"
Вадим Обозин
Вадим Обозин

Здравствуйте, записался на курс. При этом ставил галочку на "обучаться с тьютором". На email пришло письмо, о том, что записался на самостоятельное изучение курса. Как выбрать тьютора?