автордың кітабын онлайн тегін оқу Гибкая разработка веб-приложений в среде Rails
Научный редактор Н. Вильчинский
Переводчик Н. Вильчинский
Технический редактор Е. Милюкова
Литературный редактор О. Некруткина
Художник Л. Адуевская
Корректоры И. Тимофеева, И. Тимофеева
Верстка Л. Егорова
С. Руби, Д. Томас, Д. Хэнссон
Гибкая разработка веб-приложений в среде Rails. 4-е изд.. — СПб.: Питер, 2021.
ISBN 978-5-459-00312-3
© ООО Издательство "Питер", 2021
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.
Предисловие к четвертому изданию
Когда Дэйв попросил меня присоединиться к этому проекту в качестве соавтора третьего издания книги, я испытал глубокое волнение. В конце концов, ведь я изучал Rails по первому изданию этой книги. Кроме того, у меня с Дэйвом много общего. Хотя он предпочитает Emacs и Mac OS X, а я люблю Vim и Ubuntu, оба мы отдаем предпочтение командной строке, и наши пальцы привыкли набивать код, а прежде чем углубляться в сплошную теорию, мы начинаем с реальных примеров.
Со времени публикации третьего издания (фактически со времени выхода первого, второго и третьего изданий) многое успело измениться. Rails находится в процессе глубокой переработки, затрагивающей внутреннее устройство. Многие средства, применявшиеся в предыдущих примерах, сначала попали в разряд не рекомендуемых, а затем и вовсе были удалены. Были добавлены новые средства, и, кроме того, был накоплен огромный опыт наилучшего использования Rails. Теперь Rails работает с Ruby 1.9, и каждый пример был протестирован как с Ruby 1.8.7, так и с Ruby 1.9.2.
Rails выросла из популярной среды в активную и полную жизни экосистему, укомплектованную популярными дополнительными модулями и глубоко интегрированную в сторонние инструментальные средства. В процессе своего развития среда Rails превратилась в общепринятое средство, привлекающее все более разнообразный контингент разработчиков.
Все это заставило изменить структуру книги. Многие новички в Rails не знали о языке Ruby, поэтому данный раздел переместился из приложения в первую часть книги, став отдельной главой. Затем настал черед разработки приложения, которое было обновлено и упрощено с прицелом на текущий позитивный опыт.
Но наибольшим изменениям подверглась заключительная часть. Поскольку сейчас нет смысла обсуждать всю систему Rails, огромную и постоянно меняющуюся, эта часть сконцентрирована на общей концепции всей структуры, позволяющей читателю понять, что нужно искать и где можно найти дополнительные модули и сопутствующие инструментальные средства, отвечающие запросам, выходящим далеко за рамки содержимого самой среды.
Короче говоря, эта книга нуждалась в очередной переделке.
Сэм Руби (Sam Ruby)
Предисловие к версии книги для Rails 3.1
Эта книга о Rails 3.1.
Даже с учетом того, что, согласно заявлению, Rails 3.1 является промежуточным выпуском и включает в себя минимальное количество более-менее существенных изменений (конечно, по сравнению с изменениями, которые произошли между Rails 2.3.x и Rails 3.0), этот выпуск содержит значительное количество новшеств, с которыми столкнутся пользователи.
Рассмотрим краткий обзор некоторых наиболее существенных изменений:
• Сгенерированный код «знает», какую версию Ruby вы используете. В результате этого появляются преимущества от использования нового, более простого синтаксиса значений хэша, который стал доступен в Ruby 1.9.2, что влечет за собой изменение формата вывода тестовых данных.
• Управление ресурсами теперь стало частью ядра Rails. Это изменило местонахождение ряда файлов и привело к добавлению еще одного шага к развертыванию приложения.
• По умолчанию стало доступно использование SCSS, что изменило как синтаксис, так и организацию всех таблиц стилей.
• Библиотека JQuery заменила Prototype и Script.aculo.us, что повлекло за собой изменения в коде JavaScript, который вы будете создавать в главе 11 «Задача Е: добавление AJAX».
• По умолчанию стала доступна библиотека CoffeeScript, изменившая синтаксис сценариев, выполняемых на стороне клиента.
• Методы миграций перестали быть методами класса и в большинстве своем стали автоматически реверсируемыми.
• Теперь по умолчанию для преобразования ответов в последовательную форму используется не XML, а JSON. Также появился новый вспомогательный метод представления по имени j, облегчающий создание JSON-ответов (и, в целом, JavaScript).
• К модели добавился метод has_secure_password, инкапсулирующий и стандартизирующий логику хэширования обычного пользовательского пароля.
• В рабочем режиме по умолчанию стал доступен модуль Rack::Cache.
• Gem-пакет mysql был заменен gem-пакетом mysql2.
Дополнительные подробности можно найти в примечании к выпуску1.
Для запуска примеров, представленных в данной книге, важно установить правильную версию Rails в соответствии с описаниями, которые даны в главе 1 «Установка Rails». Если вы примете решение загрузить примеры в соответствии с описанием, которое дано в разделе введения «Как читать эту книгу», убедитесь в том, что вы выбрали файлы из каталога rails31.
Для определения номера запущенной версии Rails можно выполнить в командной строке команду rails –v.
Дополнительная информация, касающаяся изменений, внесенных в Rails, которые влияют на материал данной книги, может быть найдена по адресу http://www.pragprog.com/wikis/wiki/ChangesToRails.
Благодарности
Вы, наверное, думаете, что на выпуск нового издания книги нужно потратить меньше усилий. Ведь, в конце концов, весь текст уже есть. Остается только подправить кое-где код, внести в некоторые места незначительные правки — и дело в шляпе. Да не тут-то было...
Трудно передать все в точности, но у нас сложилось впечатление, что создание каждого издания этой книги требовало от нас чуть ли не больше усилий, чем выпуск самого первого издания. Rails постоянно развивается, и вместе с ней изменяется и данная книга. Части приложения Depot переписывались по нескольку раз, кроме этого обновлялись все комментарии к этому коду. Акцент на применении REST и исключение ряда средств по мере того, как они попадали в разряд не рекомендуемых, неоднократно приводили к изменению структуры книги, как только горячее становилось еле теплым.
Поэтому данная книга не появилась бы на свет без огромной помощи со стороны сообществ Ruby и Rails. Для начала перечислю очень полезных официальных рецензентов проектов данной книги:
Джереми Андерсон (Jeremy Anderson), Кен Коар (Ken Coar), Джеф Коэн (Jeff Cohen), Джоел Клермонт (Joel Clermont), Джеф Дрейк (Geoff Drake), Паван Горакави (Pavan Gorakavi), Майкл Юревич (Michael Jurewitz), Майкл Линдсаар (Mikel Lindsaar), Пол Рейнер (Paul Rayner), Мартин Реверс (Martin Reuvers), Даг Ротен (Doug Rhoten), Гари Шерман (Gary Sherman), Даванум Шринивас (Davanum Srinivas), Стефан Туралски (Stefan Turalski) и Хосе Валим (José Valim).
Кроме этого, каждое издание данной книги выпускалось в бета-версии: каждая версия публиковалась в PDF-формате, и люди комментировали ее в Интернете. В результате оставленных ими комментариев только для этого издания поступило 800 предложений и сообщений об ошибках.
Значительная часть предложений в конечном итоге была принята, что сделало эту книгу намного полезнее. Хотя наша благодарность распространяется на всех, кто поддерживал программу выпуска бета-версии книги и внес в своих отзывах так много ценных предложений, среди них есть люди, которые при этом вносили свой вклад не по долгу службы:
Мануэль Э. Видаурре Аренас (Manuel E. Vidaurre Arenas), Сет Арнолд (Seth Arnold), Уилл Боулин (Will Bowlin),Энди Брайс (Andy Brice), Джейсон Катена (Jason Catena), Виктор Мариус Костан (Victor Marius Costan), Дэвид Хэдли (David Hadley), Джейсон Холловей (Jason Holloway), Дэвид Капп (David Kapp), Trung LE, Кристиан Рибер Мандруп (Kristian Riiber Mandrup), mltsy, Стив Николсон (Steve Nicholson), Джим Палс (Jim Puls), Джонатан Ритци (Johnathan Ritzi), Leonel S, Ким Шриер (Kim Shrier), Дон Смит (Don Smith), Джо Страйтиф (Joe Straitiff) и Мартин Золлер (Martin Zoller).
И наконец, огромная помощь была оказана со стороны команды разработчиков ядра Rails, представители которой отвечали на вопросы, проверяли наши фрагменты кода и исправляли ошибки. Мы говорим огромное спасибо следующим специалистам:
Скотт Баррон (Scott Barron, htonl), Джеймис Бак (Jamis Buck, minam), Томас Фатч (Thomas Fuchs, madrobby), Джереми Кемпер (Jeremy Kemper, bitsweat), Иегуда Кац (Yehuda Katz, wycats), Майкл Козарски (Michael Koziarski, nzkoz), Марсель Молина мл. (Marcel Molina Jr, noradio), Рик Олсон (Rick Olson, technoweenie), Николас Секар (Nicholas Seckar, Ulysses), Сэм Стефенсон (Sam Stephenson, sam), Тобиас Лютке (Tobias Lütke, xal), Хосе Валим (José Valim, josevalim) и Флориан Вебер (Florian Weber, csshsh).
Сэм Руби (Sam Ruby)
Введение
Ruby on Rails является средой, облегчающей разработку, развертывание и обслуживание веб-приложений. За время, прошедшее с ее начального выпуска, Rails прошла путь от малоизвестной технологии до феномена мирового масштаба и, что более важно, стала именно той средой, которую выбирают, чтобы создавать так называемые приложения Web 2.0.
Почему это произошло?
Просто Rails хорошо прижилась с самого начала. Большое количество разработчиков было недовольно теми технологиями, которые применялись ими для создания веб-приложений. И дело, наверное, не в том, что именно они использовали — Java, PHP или .NET, — у них накапливалось ощущение излишней трудоемкости их работы. А затем в один прекрасный момент пришла Rails, с которой работать стало намного проще.
Но сама по себе простота не означает упрощенность. Речь идет о профессиональных разработчиках, создающих по-настоящему востребованные во всем мире веб-сайты. Им хочется видеть созданные ими приложения выдержавшими испытание временем — спроектированными и разработанными с использованием современных, профессиональных технологий. Поэтому разработчики занялись Rails всерьез и обнаружили, что она является не только инструментом для разработки веб-сайтов.
К примеру, все Rails-приложения выполняются с использованием архитектуры Модель-Представление-Контроллер (Model-View-Controller, MVC). Привычная Java-разработчикам среда выполнения, к примеру Tapestry или Struts, тоже основана на MVC. Но Rails идет в использовании MVC еще дальше: при ведении разработки в Rails вы начинаете уже с работающего приложения, в котором есть место для каждой части кода, и все части вашего приложения стандартным образом взаимодействуют друг с другом.
Профессиональные программисты пишут тесты. И Rails опять вносит свою лепту. Все Rails-приложения имеют встроенное тестирование. По мере добавления к программному коду какой-либо функциональной возможности, Rails автоматически создает программные заглушки тестов, предназначенные для ее тестирования. Эта среда облегчает тестирование своих приложений, подстегивая тем самым разработчиков к этому занятию.
Rails-приложения пишутся на Ruby — современном объектно-ориентированном языке сценариев. Лаконичность кода Ruby не влияет на его разборчивость — свои идеи на этом языке можно выражать вполне четко и естественно. В результате чего программы легко пишутся и (что не менее важно) по прошествии нескольких месяцев вполне легко читаются.
Rails использует все возможности Ruby, являясь его оригинальным расширением, облегчающим жизнь программистов. Программы становятся короче, читаются легче. Это также позволяет нам выполнять те задачи, которые иначе выполнялись бы в исходном коде внешних файлов конфигурации. Это облегчает понимание происходящего. Следующий код определяет для проекта модель класса. Сейчас не стоит вдаваться в детали этого кода — лучше просто подумать о том, как много информации было выражено в каких-то нескольких строках программы.
class Project < ActiveRecord::Base
belongs_to :portfolio
has_one :project_manager
has_many :milestones
has_many :deliverables, through: milestones
validates :name, :description, presence: true
validates :non_disclosure_agreement, acceptance: true
validates :short_name, uniqueness: true
end
Укоротить код Rails и сделать его более читаемым позволяют две другие философские основы этой среды: DRY и превалирование соглашения над конфигурацией. DRY означает «don’t repeat yourself», то есть «никогда не повторяться»: каждая частичка знаний в системе должна быть выражена только в одном месте. Чтобы воплотить все это в жизнь, Rails пользуется всей эффективностью языка Ruby. В Rails-приложениях можно увидеть лишь малую долю повторений, то, что нужно сказать, говорится только в одном месте, которое зачастую предлагается соглашениями о MVC-архитектуре, и далее об этом можно уже не беспокоиться. Для программистов, привыкших работать в других средах веб-разработки, где простое изменение может заставить их вносить в код программы полдюжины, а то и больше правок, это было открытием.
Превалирование соглашения над конфигурацией является не менее важным принципом. Он означает, что в Rails практически для каждого аспекта, связывающего в единое целое ваше приложение, имеются рациональные умолчания. Следуйте соглашениям, и тогда вы сможете написать Rails-приложение, используя меньше кода, чем в обычном веб-приложении, написанном на Java и использующем XML-конфигурацию. Если нужно переписать соглашения, Rails облегчает и эту задачу.
Разработчики, которые переходят на Rails, замечают еще одну особенность. Rails не играет в догонялки со ставшими де-факто новыми стандартами: напротив, она помогает их определять. К тому же Rails облегчает разработчикам интегрирование в их код таких функций, как интерфейсы AJAX и RESTful, поскольку их поддержка уже встроена в Rails. (Если вы не знакомы с интерфейсами AJAX и REST, не стоит беспокоиться, чуть позже мы объясним вам, что это такое.)
Разработчики озабочены также развертыванием своих продуктов. И тут оказывается, что с Rails можно распространять удачную версию своего приложения на любое количество серверов всего лишь одной командой (и так же легко возвращать все назад, если версия окажется не вполне удачной).
Rails была выделена из реального коммерческого приложения. Оказалось, что лучшим способом создания среды является определение основных составляющих конкретного приложения, а затем занесение их в общий фонд кода. При разработке Rails-приложения в вашем распоряжении с самого начала уже имеется половина по-настоящему хорошего приложения.
Но у Rails еще есть кое-что такое, что трудно поддается описанию. Она каким-то непостижимым образом создает уверенность в правильном выборе. Разумеется, пока вы самостоятельно не напишете на Rails какие-нибудь приложения (что может произойти в ближайшие 45 минут), вам придется поверить нам на слово. Обо всем этом и будет рассказано в нашей книге.
Rails является средством гибкой разработки
Эта книга называется «Гибкая разработка веб-приложений в среде Rails». Возможно, вы удивитесь, обнаружив отсутствие четко обозначенных разделов, посвященных использованию гибких методов Rails-программирования.
Объясняется это простыми и в то же время довольно тонкими обстоятельствами. Дело в том, что гибкость разработки является качественной составляющей Rails.
Давайте взглянем на ценные положения, которые изложены в Манифесте по гибкой разработке (Agile Manifesto), как на набор из четырех предпочтений2:
• личностей и их взаимодействия над процессами и инструментами;
• работающего программного обеспечения над подробной документацией;
• сотрудничества с заказчиком над контрактными обязательствами;
• реакций на изменения над следованием плану.
В Rails предпочтение целиком отдается людям и их взаимодействию. В ней отсутствует громоздкий инструментарий, нет ни сложных конфигураций, ни детально проработанных процессов. Вполне достаточно небольших групп разработчиков с привычными текстовыми редакторами и фрагментами Ruby-кода. Этот подход ведет к такой прозрачности, при которой все, что делается разработчиками, немедленно отражается на том, что видит заказчик. По сути, это интерактивный процесс.
Rails не отвергает документацию. Создание в этой среде HTML-документации для всего программного кода сводится к весьма простой задаче. Но процесс разработки в Rails не регулируется какими-либо документами. Вы не найдете в основе Rails-проекта 500-страничной спецификации. Вместо нее будет группа пользователей и разработчиков, совместно изучающих свои потребности и возможные пути их удовлетворения. Вы найдете решения, изменяющиеся по мере того, как и разработчики, и пользователи набираются опыта, пытаясь решить возникающие проблемы. Вы найдете среду, предоставляющую работоспособное программное обеспечение на ранней стадии цикла разработки. Это программное обеспечение может быть грубоватым, но зато оно даст пользователям возможность составить начальное представление о том, что они от вас получат. Таким образом, Rails поощряет сотрудничество с заказчиком. Когда заказчики видят, насколько быстро Rails-проект может реагировать на изменения, они начинают верить, что команда способна поставить им то, что требуется, а не только то, что было изначально запрошено. Конфронтации подменяются разговорами на тему: «А что, если…?».
Все это привязано к идее возможности реагировать на изменения. Одержимость, с которой в Rails придерживаются принципов DRY, означает, что изменения в Rails-приложениях оказывают намного меньше влияния на программный код, чем в других средах. А так как Rails-приложения пишутся на Ruby, где понятия могут выражаться четко и кратко, изменения чаще всего локализованы и легко вносятся в программный код. Существенный упор как на блочное, так и на функциональное тестирование, наряду с поддержкой в процессе тестирования испытательных стендов и программных заглушек, предоставляет разработчикам страховку, столь необходимую при внесении изменений. При хорошем наборе тестов изменения меньше действуют на нервы.
Вместо постоянных попыток связать процессы, происходящие в Rails, с принципами гибкой разработки, мы решили позволить этой среде самой раскрыть свои возможности. По мере чтения глав руководства попытайтесь представить себе, что вы ведете разработку веб-приложения, работая рядом со своими заказчиками и совместно вырабатывая приоритеты и решения проблем. Затем, при переходе в части третьей к изучению самых передовых концепций, посмотрите, как структура, положенная в основу Rails, может позволить вам быстрее и с меньшей долей формализма удовлетворять потребности ваших заказчиков.
И еще одно, последнее замечание по поводу гибкой разработки и Rails: хотя упоминание об этом может выглядеть непрофессионально, но подумайте, насколько веселее станет сам процесс программирования!
Для кого предназначена эта книга
Эта книга предназначена для программистов, присматривающихся к созданию и развертыванию веб-приложений. К их числу относятся прикладные программисты, не работавшие ранее с Rails (и, возможно, даже незнакомые с Ruby), и программисты, знакомые с основами, но желающие прийти к более глубокому пониманию среды Rails.
Предполагаются некоторые познания в HTML, Cascading Style Sheets (CSS) и JavaScript, иными словами, речь идет о способности разбираться в исходном коде веб-страниц. Вам не нужно быть экспертами по данной тематике, самое сложное, что предстоит делать, — это переносить в файлы программный материал этой книги, весь объем которого можно загрузить.
Как нужно читать эту книгу
Первая часть этой книги является подготовительной. После ее прочтения вы получите начальное представление о языке Ruby и общее представление о самой среде Rails, у вас будут установлены Ruby и Rails, и вы проверите работоспособность этой установки на простом примере. В следующей части на более объемном примере (создание простого интернет-магазина) вы изучите концепции, положенные в основу Rails. Здесь не будет последовательного путешествия по каждому из компонентов Rails («вот глава о моделях, а вот о представлениях» и т.д.). Эти компоненты созданы для совместной работы, и каждая глава в этой части привязана к конкретному набору родственных задач, в решение которых вовлекается сразу несколько совместно работающих компонентов.
Многим, похоже, нравится создавать приложение по мере чтения этой книги. Если вам не хочется набирать код, можно схитрить, загрузив исходный код (сжатый tar-архив или zip-файл3). Эта загрузка содержит отдельные наборы исходного кода для Rails 3.0 и Rails 3.1. Нужные вам файлы будут находиться в каталоге rails31. Подробности изложены в файле README-FIRST.
В части третьей, «Углубленное изучение Rails», рассматривается вся экосистема Rails. Эта часть начинается с функций и возможностей Rails, с которыми вы уже ознакомились. Затем охватывается ряд ключевых зависимостей, используемых средой Rails, которые вносят непосредственный вклад в общую функциональность, предоставляемую этой средой. И наконец, в ней рассматривается ряд популярных дополнительных модулей, расширяющих среду Rails и превращающих ее из простой среды в открытую экосистему.
При чтении книги вам будут попадаться различные принятые нами способы оформления текста.
Исполняемый код
Большинство демонстрируемых фрагментов кода взяты из полноценных, работоспособных примеров, которые можно загрузить.
Если листинг кода можно найти в загружаемых примерах, чтобы облегчить задачу его поиска, перед ним будет стоять заголовок (такой же, как в следующем примере).
rails31/work/demo1/app/controllers/say_controller.rb
class SayController < ApplicationController
end
end
end
В этом заголовке содержится путь к листингу в скачанной структуре исходного кода. А в некоторых случаях, где используются модификации существующих файлов и где трудно заметить измененные строки, слева от таких строк можно заметить значки в виде треугольников, помогающие их распознать. Две такие строки показаны в предыдущем примере кода.
Дэвид говорит…
Время от времени вам будут попадаться врезки «Дэвид говорит…». В них Дэвид Хайнемайер Хэнсон (David Heinemeier Hansson) будет делиться с вами ценными сведениями о Rails — давать пояснения и рекомендации, показывать трюки и т.п. Поскольку он создатель Rails, эти врезки не стоит пропускать, если вы хотите подойти к изучению этой среды профессионально.
Джо спрашивает…
В книге иногда появляется некий мифический разработчик по имени Джо, задающий вопросы по существу изучаемого материала, на которые мы отвечаем.
Эта книга не является справочным руководством по Rails. Наш опыт подсказывает, что справочные руководства для большинства людей учебниками служить не могут. Вместо этого мы показали большинство модулей и многие из их методов либо в примерах, либо в текстовых описаниях в контексте использования этих компонентов и их совместной работы.
Вы не найдете здесь и многих сотен страниц с листингами API-функций. Для этого есть серьезные основания — вы получаете всю соответствующую документацию при каждой установке Rails, и она, несомненно, будет новее того материала, который представлен в данной книге. Если вы устанавливаете Rails, используя RubyGems (что соответствует нашим рекомендациям), нужно просто запустить сервер gem-документации (воспользовавшись командой gem_server), и вы сможете получить доступ к описанию всех API-функций Rails, набрав в адресной строке браузера http://localhost:8808. Создание дополнительной документации и руководств будет рассмотрено в главе 18, в разделе «Место для документации».
Кроме этого, вы увидите, что сама Rails помогает вам, создавая ответы, четко идентифицирующие любую найденную ошибку, а также показывая пути, сообщающие вам не только о месте обнаружения ошибки, но и о том, как до него добраться. Пример можно увидеть на рис. 10.3. Если нужна дополнительная информация, загляните в раздел 10.2 «Шаг Д2: обработка ошибок», чтобы увидеть как можно вставить инструкции для ведения регистрационного журнала.
Если вы на чем-то застопоритесь, помощь можно будет найти в огромной массе интернет-ресурсов. Вдобавок к упомянутым ранее листингам, есть еще форум4, где вы можете задавать вопросы и делиться опытом, перечень замеченных опечаток5, где вы можете сообщить об ошибках, и wiki6, где вы можете обсудить упражнения, которые приводятся по всей книге.
Это общедоступные ресурсы, и вы можете вполне свободно помещать на форуме и wiki не только вопросы и проблемы, но также и любые предложения, и ответы на вопросы, заданные другими людьми.
Итак, приступим! Первым нашим шагом будет установка Ruby и Rails и проверка работоспособности этой установки на простом примере.
2 http://agilemanifesto.org/. Дэйв Томас был одним из 17 авторов этого документа.
3 Скачайте файлы с сайта издательства «Питер» www.piter.com или по адресу http://pragprog.com/titles/rails4/source_code
Давайте взглянем на ценные положения, которые изложены в Манифесте по гибкой разработке (Agile Manifesto), как на набор из четырех предпочтений2:
Дополнительные подробности можно найти в примечании к выпуску1.
Если вы на чем-то застопоритесь, помощь можно будет найти в огромной массе интернет-ресурсов. Вдобавок к упомянутым ранее листингам, есть еще форум4, где вы можете задавать вопросы и делиться опытом, перечень замеченных опечаток5, где вы можете сообщить об ошибках, и wiki6, где вы можете обсудить упражнения, которые приводятся по всей книге.
Если вы на чем-то застопоритесь, помощь можно будет найти в огромной массе интернет-ресурсов. Вдобавок к упомянутым ранее листингам, есть еще форум4, где вы можете задавать вопросы и делиться опытом, перечень замеченных опечаток5, где вы можете сообщить об ошибках, и wiki6, где вы можете обсудить упражнения, которые приводятся по всей книге.
http://agilemanifesto.org/. Дэйв Томас был одним из 17 авторов этого документа.
Скачайте файлы с сайта издательства «Питер» www.piter.com или по адресу http://pragprog.com/titles/rails4/source_code
Если вы на чем-то застопоритесь, помощь можно будет найти в огромной массе интернет-ресурсов. Вдобавок к упомянутым ранее листингам, есть еще форум4, где вы можете задавать вопросы и делиться опытом, перечень замеченных опечаток5, где вы можете сообщить об ошибках, и wiki6, где вы можете обсудить упражнения, которые приводятся по всей книге.
Многим, похоже, нравится создавать приложение по мере чтения этой книги. Если вам не хочется набирать код, можно схитрить, загрузив исходный код (сжатый tar-архив или zip-файл3). Эта загрузка содержит отдельные наборы исходного кода для Rails 3.0 и Rails 3.1. Нужные вам файлы будут находиться в каталоге rails31. Подробности изложены в файле README-FIRST.
Часть I. Начало
Глава 1. Установка Rails
Основные темы:
В первой части этой книги вам будут представлены язык Ruby и среда Rails. Но сначала нужно установить оба этих средства и убедиться в их работоспособности.
Чтобы среда Rails заработала на вашей системе, нужно располагать следующими программными средствами:
• интерпретатором Ruby. Система Rails написана на Ruby, и свои приложения вы также будете создавать на Ruby. Rails 3.1 требует применения Ruby версии 1.9.2 или Ruby 1.8.7. На Ruby 1.8.6 и Ruby 1.9.1 эта среда работать не будет.
Те различия в версиях Ruby, которые касаются материала данной книги, рассмотрены в ближайшей врезке;
• используемой в Ruby cистемой упаковки программных средств, а именно RubyGems. Этот выпуск основан на RubyGems версии 1.8.7;
• системой Ruby on Rails. Эта книга была написана с использованием Rails версии 3.1 (на данный момент это Rails 3.1.0);
• интерпретатором JavaScript. Встроенные интерпретаторы этого языка имеются как в Microsoft Windows, так и в Mac OS X, и Rails будет использовать ту версию, которая уже установлена на вашей системе. В других операционных системах может понадобиться отдельная установка интерпретатора JavaScript;
• некоторыми библиотеками, в зависимости от операционной системы;
• базой данных. В данной книге используются как SQLite 3, так и MySQL 5.1.
Для машины, используемой в целях разработки программ, это практически все, что нужно (не считая редактора, но о редакторах мы поговорим отдельно). Если же вам захочется ввести приложение в эксплуатацию, дополнительно понадобится установить промышленный веб-сервер (как минимум), а также поддерживающее его программное обеспечение, без которого эффективная работа Rails невозможна. Этому посвящена целая глава, и здесь данный вопрос больше рассматриваться не будет.
Ну и как же все это устанавливать? А это зависит от вашей операционной системы...
Выбор версии Ruby
Материал этой книги рассчитан на использование Ruby 1.9.2. Хотя Rails 3.1 работает с Ruby 1.8.7 или с Ruby 1.9.2, команда разработчиков ядра Rails рекомендует для всех новых Rails-приложений использовать Ruby 1.9.2. У этой версии более совершенный синтаксис и повышенная производительность. Более того, ожидается, что в Rails 4.0 поддержка Ruby 1.8.7 будет прекращена.
Если вы все же решите установить или оставить на компьютере уже установленную версию Ruby 1.8.7, некоторые генерируемые временные платформы (scaffold) будут использовать «старый» хэш-синтаксис. «Новый» хэш-синтаксис имеет следующий вид:
redirect_to @cart, notice: 'Корзина успешно создана.'
А вот как выглядит тот код, который будет сгенерирован Rails 3.1 вместо него при использовании Ruby 1.8.7:
redirect_to @cart, :notice => ' Корзина успешно создана.'
Обратите внимание на изменение позиции символа двоеточия и на дополнительную стрелку, составленную из знаков равенства и «больше чем».
Также следует учесть и изменения формата вывода тестов.
Если постоянно помнить об этих двух факторах, то книгу можно использовать для изучения Rails 3.1 с использованием Ruby 1.8.7.
1.1. Установка под Windows
Самым простым способом установки Rails под Windows является использование пакета RailsInstaller7. Нужно лишь убедиться, что вы имеете дело с версией 2.0, включающей в себя Ruby 1.9.2 и Rails 3.1. На время написания данной книги RailsInstaller 2.0 был доступен только в предварительном выпуске, ссылка на который приведена в сноске. Пока не выйдет окончательная версия пакета, можно спокойно пользоваться его предварительной версией.
Основная установка происходит довольно просто. После загрузки щелкните на кнопке Run, затем на кнопке Next. Установите переключатель в положение «I accept the License» (разумеется, после внимательного прочтения самой лицензии, условия которой принимаются) и щелкните на кнопках Next>Install>Finish.
После этого будет открыто окно командной строки и выдано приглашение на ввод имени и адреса электронной почты. Это нужно только лишь для настройки версии системы управления Git. Генерируемый ssh-ключ для выполнения упражнений данной книги не понадобится.
Закройте это окно и откройте новое окно командной строки, щелкнув на кнопке Пуск (Start) и выбрав пункт Выполнить... (Run...), после чего введите cmd и щелкните на кнопке OK.
А теперь пользователи Windows могут перейти сразу к разделу 1.4, «Выбор версии Rails». Там мы и встретимся.
1.2. Установка под Mac OS X
Поскольку ни Snow Leopard, ни Lion не имеют предустановленного Ruby 1.9.2, придется загружать и встраивать его самостоятельно. По нашему мнению, проще всего это сделать с помощью RVM. Установка RVM рассмотрена на веб-сайте RVM8. В общих чертах эти действия рассматриваются и в данной главе.
Во-первых, нужно убедиться в установке Xcode 3 или более поздней версии. При работе под управлением Mac OS X 10.7 (Lion) в качестве бесплатного дополнения можно загрузить Xcode 4.19 из Mac App Store, и это средство будет автоматически установлено на ваш компьютер Mac. При работе под управлением Mac OS X 10.6 (Snow Leopard) нужно установить Xcode с компакт-диска Snow Leopard, поставляемого с компьютером Mac. Xcode можно найти в каталоге Optional Installs. Проверьте установку, запустив следующую команду:
$ xcodebuild -version
Если установлен инструментарий Xcode версии 3, отдельно необходимо будет установить нужную версию системы управления Git. Загрузите10 и установите ту версию, которая соответствует версии вашей операционной системы и оборудованию. Проверьте установку, запустив следующую команду:
$ git —version
Затем установите сам диспетчер RVM:
$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
Следуйте инструкциям по установке, выдаваемым данной командой. В частности, нужно добавить установочные инструкции RVM-функции в ваш файл .bash_profile:
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && \
. "$HOME/.rvm/scripts/rvm"' >> ~/.bash_profile
Выйдите из окна командной строки или приложения Terminal и откройте их новый экземпляр. Это приведет к перезагрузке с использованием вашего файла .bash_profile. В этом новом окне установите сам интерпретатор Ruby:
$ rvm install 1.9.2
Предыдущее действие потребует времени на загрузку, конфигурацию и компиляцию необходимых исполняемых файлов. Как только работа будет завершена, воспользуйтесь этой средой окружения и установите Rails:
$ rvm use 1.9.2
$ gem install rails
За исключением инструкции rvm use, каждая из приведенных выше инструкций должна быть выполнена только один раз. Инструкцию rvm use нужно повторять при каждом открытии окна оболочки. Ключевое слово use является необязательным, поэтому инструкцию можно сократить до вида rvm 1.9.2. Можно также для новых сеансов работы с терминалом сделать эту версию интерпретатора Ruby используемой по умолчанию, воспользовавшись следующей командой:
$ rvm —default 1.9.2
Убедиться в успехе установки можно с помощью следующей команды:
$ rails -v
Если возникнут проблемы, воспользуйтесь рекомендациями, перечисленными на веб-сайте rvm под заголовком «Troubleshooting Your Install»11.
А теперь пользователи OS X могут перейти сразу к разделу 1.4, «Выбор версии Rails», чтобы присоединиться к пользователям Windows. Там мы и встретимся.
1.3. Установка под Linux
Начните с одной из систем управления пакетами, принадлежащей вашей платформе: apt-get, dpkg, portage, rpm, rug, synaptic, up2date или yum.
Сначала нужно установить необходимые взаимодействующие средства. Следующие инструкции предназначены для Ubuntu 11.04, Natty Narwhal; при работе под другими операционными системами и отсутствии уверенности в имеющихся в них установках самыми важными устанавливаемыми на данном этапе пакетами являются git и curl, а все остальные пакеты можно будет установить по мере необходимости.
$ sudo apt-get install apache2 curl git libmysqlclient-dev mysql-server nodejs
У вас будет запрошен корневой пароль для вашего сервера MySQL. Если оставить его поле пустым, он будет запрошен еще несколько раз. Если будет указан пароль, его нужно будет использовать при создании базы данных, которое рассматривается в главе 16, в разделе «Использование MySQL для создания базы данных».
Поскольку в Ubuntu 11.04 нет предустановленного Ruby 1.9.2, нужно будет его загрузить и встроить. По нашему мнению, для этого проще всего воспользоваться диспетчером RVM. Установка RVM рассмотрена на веб-сайте RVM12. В общих чертах эти действия рассматриваются и в данной главе.
Сначала устанавливается сам RVM:
$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
Следуйте инструкциям по установке, выдаваемым данной командой. В частности, нужно добавить установочные инструкции RVM-функции в ваш файл .bash_profile:
$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && \
. "$HOME/.rvm/scripts/rvm"' >> ~/.bash_profile
Выйдите из окна командной строки или приложения Terminal и откройте их новый экземпляр. Это приведет к перезагрузке с использованием вашего файла .bash_profile.
Выполните следующую команду, которая предоставляет дополнительные инструкции по установке применительно к вашей операционной системе:
$ rvm notes
Найдите строку, в которой рассказывается, как установить необходимые дополнения к операционной системе для работы с Ruby (MRI). После выполнения всех этих инструкций можно перейти к установке самого интерпретатора Ruby:
$ rvm install 1.9.2
Предыдущий этап установки потребует времени на загрузку, конфигурирование и компиляцию необходимых исполняемых файлов. Как только он будет завершен, воспользуйтесь созданной средой и установите Rails:
$ rvm use 1.9.2
$ gem install rails
За исключением инструкции rvm use, каждая из показанных выше инструкций должна быть выполнена только один раз. Инструкцию rvm use нужно повторять при каждом открытии окна оболочки. Ключевое слово use является необязательным, поэтому инструкцию можно сократить до вида rvm 1.9.2. Можно также для новых сеансов работы с терминалом сделать эту версию интерпретатора Ruby используемой по умолчанию, воспользовавшись следующей командой:
$ rvm —default 1.9.2
Убедиться в успехе установки можно с помощью следующей команды:
$ rails -v
Если возникнут проблемы, воспользуйтесь рекомендациями, перечисленными на веб-сайте rvm под заголовком «Troubleshooting Your Install»13.
Теперь, когда были рассмотрены инструкции для Windows, Mac OS X и Linux, все последующие инструкции будут общими для всех трех операционных систем.
1.4. Выбор версии Rails
Предыдущие инструкции помогли вам установить самую последнюю версию Rails. Но порой именно самая последняя версия может и не понадобиться. Например, может потребоваться запустить версию Rails, соответствующую той версии, которая использовалась при создании данной книги, чтобы была уверенность в том, что выводимые данные и примеры полностью соответствуют изложенному материалу. Или, возможно, разработка ведется на одной машине, но эксплуатация предполагается на другой, содержащей неподконтрольную вам версию Rails.
Попав в какую-либо из подобных ситуаций, нужно быть в курсе нескольких вещей. Сначала нужно с помощью команды gem найти все установленные версии Rails:
$ gem list —local rails
Также нужно с помощью команды rails —version проверить, какая версия Rails запускается по умолчанию. Эта команда должна вернуть 3.1.0 или индекс более свежей версии.
Установка другой версии Rails также осуществляется через команду gem. В зависимости от вашей операционной системы, может понадобиться предварить ее командой sudo.
$ gem install rails —version 3.1.0
При наличии сразу нескольких версий Rails никто не сможет добиться нужного результата, пока не будет способа выбора одной из них. И такой способ есть. Вызывая любую команду rails, можно указать, какая версия Rails будет использоваться, вставив перед первым аргументом команды полный номер версии, окруженный символами подчеркивания:
$ rails _3.1.0_ —version
Это особенно важно при создании нового приложения, поскольку, если приложение создано с использование конкретной версии Rails, оно будет и дальше продолжать использовать эту версию, даже если на системе установлены более свежие версии, до тех пор, пока не будет принято решение обновить приложение. Для обновления нужно будет просто указать номер новой версии в файле Gemfile, который находится в корневом каталоге вашего приложения, и запустить команду bundle install. Более подробно эта команда будет рассмотрена в главе 25, в разделе «Управление компонентами, от которых зависит работа приложения с помощью системы Bundler».
1.5. Настройка среды разработки
Повседневная работа по созданию Rails-программ не отличается особым разнообразием, но каждый работает по-своему. Мы это делаем следующим образом.
Командная строка
Основную работу мы проделываем в командной строке. Хотя появляются все новые и новые средства графического пользовательского интерфейса (GUI), помогающие генерировать Rails-приложения и управлять ими, мы считаем, что командная строка по-прежнему является наиболее эффективным способом разработки. Поэтому вам стоит потратить немного времени на ознакомление с командной строкой вашей операционной системы. Нужно выяснить, как она используется для редактирования вводимых команд, как можно найти и отредактировать предыдущие команды и как осуществлять автозавершение вводимых имен файлов и команд.
Для оболочек Unix Bash и zsh стандартным является автозавершение с помощью клавиши табуляции (так называемое tab-завершение). Оно позволяет набирать первые несколько символов имени файла, и нажатием клавиши Tab заставлять оболочку провести поиск и завершить имя, используя соответствующие имена файлов.
Управление версиями
Вся наша работа ведется в системе управления версиями (на данный момент в Git). При создании нового Rails-проекта в Git заносится предмет проверки, и после прохождения тестов туда передаются все изменения. Обычно передача данных в репозиторий ведется по нескольку раз в час.
а где же IDE?
Если вы занялись Ruby и Rails после того, как поработали с такими языками, как C# и Java, у вас может появиться вопрос насчет IDE (интегрированной среды разработки). Ведь всем известно, что невозможно создать код современного приложения без хотя бы 100 Мбайт IDE, поддерживающего каждое нажатие клавиши. Всем, кто считает себя слишком грамотным, мы предлагаем прямо сейчас усесться поудобнее и обложиться со всех сторон грудами справочников по среде разработки и книгами по 1000 страниц на тему «как все просто можно сделать».
Для Ruby или Rails пока не существует совершенных IDE (хотя некоторые среды разработки уже на подходе). Вместо них большинство Rails-разработчиков используют старые добрые текстовые редакторы. Оказывается, не стоит драматизировать ситуацию. Используя другие, менее выразительные языки, программисты полагаются на IDE для того, чтобы она делала за них большую часть рутинной работы: генерировала код, помогала осуществлять навигацию по файловой системе и проводила постоянную компиляцию, моментально выдавая предупреждения об ошибках.
При работе с Ruby такая мощная поддержка просто ни к чему. Текстовые редакторы, наподобие TextMate, предоставят вам 90% всего, что вы получали от IDE, выступая при этом в более легком весе.
Пожалуй, единственно полезной из утраченных функций IDE будет поддержка мгновенной проверки кода.
Если работа над Rails-проектом ведется совместно с другими людьми, нужно подумать об установке распределенной системы интеграции — continuous integration system (CI). Когда кто-нибудь зарегистрирует изменения, CI-система проверит новую копию приложения и выполнит все тесты. Это самый простой способ немедленного обнаружения случайных повреждений. Можно также настроить свою CI-систему на ее использование клиентами для апробации самой последней версии вашего приложения. Такая прозрачность является отличной гарантией того, что ваш проект не уйдет в сторону от запросов потребителей.
Редакторы
Мы создаем свои Rails-программы, используя редакторы для программистов. За годы работы мы поняли, что различные редакторы хороши для работы с различными языками и средами. Например, Дэйв сначала написал эту главу, используя редактор Emacs, поскольку его режим Filladapt он считает непревзойденным, когда дело касается форматирования вводимого XML-кода. Сэм внес поправки в эту главу, используя редактор Vim. Многие считают, что ни Emacs, ни Vim не являются идеальными средствами для Rails-разработки, и предпочитают пользоваться редактором TextMate. Выбор редактора, конечно, дело сугубо личное, но в редакторе для Rails стоит все же поискать следующие свойства:
• Поддержку выделения синтаксиса Ruby и HTML. Она идеально подойдет для файлов формата .erb (формат файлов Rails, включающих в себя вставки фрагментов Ruby в HTML-код).
• Поддержку автоматических отступов и обратных отступов в исходном коде Ruby. Это свойство не только улучшает эстетическое восприятие: создание редактором отступов по мере ввода программы — это наилучший способ отслеживания неправильных структурных вложений в программном коде. Способность делать обратные отступы важна при пересмотре кода и перемещении материала. (Очень удобной представляется способность редактора TextMate обрабатывать обратные отступы после вставки кода из буфера.)
• Поддержку вставок обычных логических структур Ruby и Rails. Вам придется вводить множество коротких методов, и, если IDE создает структуру метода путем нажатия одной или двух клавишных комбинаций, вы сможете сконцентрироваться на главном материале, находящемся внутри этой структуры.
• Хорошую навигацию по файловой системе. Мы еще увидим, что Rails-приложения состоят из множества файлов: только что созданное приложение попадает в мир, состоящий из сорока шести файлов, разбросанных по тридцати четырем каталогам, — и это еще до создания конкретного наполнения этого приложения.
Вам нужна среда, помогающая осуществлять быстрые переходы: вы будете добавлять строчку к контроллеру для загрузки значения, переключаться на представление и добавлять строчку, чтобы вывести это значение на экран, а затем переключаться на тестирование, чтобы убедиться, что все сделано правильно. Такие средства, как Блокнот, в которых для выбора каждого редактируемого файла приходится работать с диалоговым окном File>Open, вряд ли будут соответствовать этому требованию. Мы предпочитаем иметь сочетание изображения дерева файлов на боковой панели, небольшого набора клавишных комбинаций, позволяющих найти по имени в дереве каталогов файл (или файлы), и некоторых встроенных механизмов, «знающих», как осуществлять переходы, скажем, между действием контроллера и соответствующим ему представлением.
• Автозавершение имен. В Rails часто встречаются довольно длинные имена. Хороший редактор позволяет вводить первые несколько символов, а затем предлагает одним нажатием клавиши ввести возможное продолжение.
Мы не решаемся рекомендовать какие-то конкретные редакторы, поскольку сами по-настоящему пользовались всего лишь несколькими из них и ненароком можем оставить чей-нибудь любимый редактор вне этого списка. Тем не менее, чтобы помочь вам начать работу с чем-нибудь посерьезнее, чем Блокнот, мы смеем предложить следующие редакторы:
• TextMate (http://macromates.com/). Редактор Ruby и Rails, выбранный нами для Mac OS X.
• Xcode 3.0 на Mac OS X с органайзером, удовлетворяющим большинству ваших потребностей. Руководство, позволяющее приступить к работе с Rails на Leopard, доступно по адресу http://developer.apple.com/tools/developonrailsleopard.html.
• Для тех, кто при любых условиях предпочтет использование TextMate, но вынужден работать под Windows, вполне подойдет E-TextEditor (http://e-texteditor.com/), предоставляющий «все возможности TextMate под Windows».
• Aptana RadRails (http://www.aptana.com/products/radrails). Интегрированная среда разработки Rails-приложений, работающая на Aptana Studio и Eclipse. Она работает под Windows, Mac OS X и Linux. В 2006 году это средство завоевало премию как лучшее открытое средство разработки на основе Eclipse, а в 2007 году этот проект стала курировать компания Aptana.
• NetBeans IDE 6.5 (http://netbeans.org/features/ruby/index.html). Эта среда работает в Windows, Mac OS X, Solaris и Linux. Доступна в пакете с поддержкой Ruby или же в пакете, допускающем последующую загрузку Ruby. В дополнение к конкретной поддержке Rails 2.0, Rake-целей и миграций баз данных, эта среда поддерживает графический мастер генератора кода Rails и быстрые переходы из действий Rails к соответствующему им отображению.
• jEdit (http://www.jedit.org/). Полнофункциональный редактор с поддержкой Ruby. Имеет встроенную поддержку внешних модулей.
• Komodo (http://www.activestate.com/komodo-ide). IDE, разработанная компанией ActiveState для динамичных языков, включая Ruby.
• RubyMine (http://www.jetbrains.com/ruby/features/index.html). Коммерческая IDE-среда для Ruby, бесплатно доступная для специальных образовательных проектов и проектов с открытым кодом. Работает под Windows, Mac OS X и Linux.
Спросите у опытных разработчиков, пользующихся такой же операционной системой, с каким редактором они работают. Перед тем как сделать окончательный выбор, попробуйте поработать около недели в различных редакторах.
Рабочий стол
Мы не собираемся указывать вам, как следует оформлять Рабочий стол при работе с Rails, но расскажем, как мы делаем это.
Чаще всего мы занимаемся написанием кода, запуском тестов и исследованием работы своего приложения в браузере. Поэтому на нашем главном Рабочем столе разработчика находятся в постоянно открытом состоянии окна редактора и браузера. Мы также хотим отслеживать регистрационные записи, генерируемые приложением, поэтому держим открытым еще и окно терминала. В нем для прокрутки содержимого регистрационного файла по мере его обновления мы пользуемся командой tail -f. Обычно это окно настроено на отображение информации очень мелким шрифтом, чтобы оно занимало меньше места, но, как только будет замечено появление чего-нибудь интересного, этот шрифт увеличивается, чтобы все можно было как следует рассмотреть.
Нам также нужен доступ к документации Rails API, которая просматривается в браузере. Во введении шла речь об использовании команды gem_server для запуска локального веб-сервера, содержащего Rails-документацию. Это, конечно, удобно, но, к сожалению, Rails-документация разбросана по нескольким отдельным справочным каталогам. Если у вас есть постоянное подключение к Интернету, вы можете воспользоваться ресурсом http://api.rubyonrails.org, чтобы увидеть всю Rails-документацию в одном месте.
1.6. Rails и базы данных
В данной книге при создании примеров использовалась база данных SQLite 3 (версии 3.7.4 или ближайших к ней версий). Если вы собираетесь придерживаться нашего кода, то, наверное, проще всего будет также воспользоваться SQLite 3. Если же будет принято решение об использовании какого-нибудь другого средства, это также не составит проблем. Возможно, для этого придется внести небольшие поправки в какой-нибудь явно выраженный SQL-фрагмент вашего кода, но Rails в своих приложениях старается максимально избавиться от специфичного для баз данных SQL-кода.
Если нужно будет подключиться к базе данных, отличной от SQLite 3, Rails также работает с DB2, MySQL, Oracle, Postgres, Firebird и SQL Server. Для всех баз данных, кроме SQLite 3, потребуется установить драйвер базы данных, библиотеку, которую Rails сможет использовать для подключения и использования вашего процессора базы данных. В этом разделе содержатся ссылки на инструкции, позволяющие справиться с этой задачей.
Все драйверы баз данных написаны на C и распространяются в основном в виде исходного кода. Если вам не хочется возиться с созданием драйвера из исходного кода, присмотритесь повнимательнее к веб-сайту драйвера. В большинстве случаев обнаружится, что автор распространяет также и двоичные версии.
СОЗДАНИЕ СВОЕЙ СОБСТВЕННОЙ ДОКУМЕТАЦИИ RAILS API
Вы можете создать собственную локальную версию сводной документации Rails API. Для этого нужно ввести в командную строку следующий набор команд:
rails_apps> rails new dummy_app
rails_apps> cd dummy_app
dummy_app> rake doc:rails
На последней стадии следует немного подождать. Когда все закончится, у вас будет документация Rails API в дереве каталогов, начинающемся с doc/api. Я советую переместить эту папку на Рабочий стол, а затем удалить дерево dummy_app.
Для просмотра документации Rails API откройте в своем браузере страницу doc/api/index.html.
Если вы не сможете найти двоичную версию или если вы все равно хотите создать драйвер из исходного кода, вам для его создания понадобится среда разработки, установленная на вашей машине. При работе под Windows это означает, что у вас должна быть копия Visual C++. При работе под Linux вам понадобится gcc и сопутствующие компоненты (которые, скорее всего, уже установлены).
При работе под OS X вам понадобится установить инструментарий разработчика (который поставляется вместе с операционной системой, но по умолчанию не устанавливается). Вам также понадобится установить драйвер вашей базы данных в подходящую версию Ruby. Если вы установили свою собственную копию Ruby в обход встроенной копии, важно помнить, что при создании и установке драйвера базы данных эта версия Ruby должна быть указана в пути поиска первой. Чтобы убедиться, что Ruby не запускается из каталога /usr/bin, можно воспользоваться командой which ruby.
В следующем списке перечислены все доступные адаптеры баз данных и приведены ссылки на веб-страницы, где они могут быть найдены:
| DB2 |
http://raa.ruby-lang.org/project/ruby-db2 или http://rubyforge.org/projects/rubyibm |
| Firebird |
|
| MySQL |
|
| Oracle |
|
| Postgres |
|
| Server |
|
| SQLite |
В списке указана фирменная Ruby-версия адаптера Postgres. Версию postgres-pr можно загрузить с веб-страницы Ruby-DBI, размещенной по адресу http://rubyforge.org/projects/ruby-dbi.
Адаптеры MySQL и SQLite также можно загрузить в виде RubyGems (соответственно, mysql и sqlite).
1.7. Наши достижения
× Установили (или обновили) интерпретатор языка Ruby.
× Установили (или обновили) среду Rails.
× Установили (или обновили) базу данных SQLite3.
× Выбрали редактор.
Теперь, имея установленную среду Rails, давайте перейдем к ее использованию. Настало время приступить к чтению следующей главы, где будет создано наше первое приложение.
Глава 2. Немедленное использование
Основные темы:
Давайте напишем простое приложение, чтобы проверить, удачно ли среда Rails была установлена на наших машинах, а также получить представление о работе Rails.
2.1. Создание нового приложения
При установке среды Rails вы также получаете новый инструмент командной строки, rails, который используется для конструирования каждого нового создаваемого вами Rails-приложения.
А зачем для этого требуется какой-то инструмент? Почему бы для этого просто не приспособить наш любимый текстовый редактор и не создать исходный код для приложения с нуля? Можно было бы, конечно, заняться и этой нудной работой. В конце концов, Rails-приложение — это всего лишь исходный код на языке Ruby. Но Rails, кроме всего прочего, творит множество скрытых чудес, заставляя наши приложения работать при минимуме явных настроек. Чтобы заставить Rails творить чудеса, ей нужно дать возможность отыскать все разнообразие компонентов вашего приложения. Далее (в разделе 18.1 «Где что искать») станет ясно, что для этого нужно создать конкретную структуру каталогов, разложив создаваемый нами код по надлежащим местам. Команда rails просто создает для нас эту структуру каталогов и заполняет ее стандартным Rails-кодом.
Для создания нашего первого Rails-приложения откройте окно командной оболочки и перейдите в то место файловой системы, в котором вы хотите создать структуру каталогов для своих приложений. В нашем примере мы будем создавать приложения в каталоге под названием work. Находясь в этом каталоге, введите команду rails для создания приложения с названием demo. Имейте в виду: если у вас уже существует каталог с таким названием, вам будет задан вопрос, не хотите ли вы перезаписать все существующие в нем файлы.
ПРИМЕЧАНИЕ
Если, как описывалось в разделе 1.4 «Выбор версии Rails» нужно указать, какую из версий Rails использовать, то это следует сделать именно здесь.
rubys> cd work
work> rails new demo
create
create README
create Rakefile
create config.ru
: : :
create vendor/plugins
create vendor/plugins/.gitkeep
run bundle install
Fetching source index for http://rubygems.org/
: : :
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
work>
Команда создала каталог по имени demo. Зайдите в него и выведите его содержимое (используя ls в окне Unix или dir при работе под Windows).
Вы должны увидеть набор файлов и подкаталогов:
work> cd demo
demo> dir /w
[.] [..] .gitignore [app] [config]
config.ru [db] [doc] Gemfile Gemfile.lock
[lib] [log] [public] Rakefile README
[script] [test] [tmp] [vendor]
Поначалу все эти каталоги (и файлы, которые в них содержатся) могут отпугнуть, но на данный момент на существование большинства из них можно просто не обращать внимания. В данной главе непосредственно будет использоваться только один из них: каталог app, в котором будет создаваться наше приложение.
Включенные туда файлы представляют собой все, что нужно для запуска автономного веб-сервера, способного выполнять наше только что созданное Rails-приложение. Давайте без лишних проволочек запустим наше приложение под названием demo:
demo> rails server
=> Booting WEBrick
=> Rails 3.1.0 application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2011-07-23 10:38:18] INFO WEBrick 1.3.1
[2011-07-23 10:38:18] INFO ruby 1.9.2 (2011-05-12) [x86_64-linux]
[2011-07-23 10:38:18] INFO WEBrick::HTTPServer#start: pid=6044 port=3000
Какой веб-сервер запущен, зависит от того, какой сервер установлен. WE-Brick — веб-сервер, специально предназначенный для Ruby, который распространяется вместе с Ruby и поэтому является гарантированно доступным. Но, если на вашей системе установлен другой веб-сервер (и Rails может его найти), команда rails server может предпочесть его серверу WEBrick. Rails можно заставить воспользоваться WEBrick, предоставив команде rails соответствующий ключ:
demo> rails server webrick
В последней строчке трассировка запуска показывает, что мы только что запустили веб-сервер с использованием порта 3000. Часть адреса 0.0.0.0 означает, что WEBrick допустит подключения ко всем интерфейсам. На установленной у Дэйва системе OS X это означает доступ к обоим локальным интерфейсам (127.0.0.1 и ::1) и его подключению к локальной сети. Мы можем получить доступ к приложению, указав веб-браузеру URL-адрес http://localhost:3000. Результат показан на рис. 2.1.
Если смотреть в окно, из которого был запущен сервер, вы увидите трассировку, показывающую, что вы запустили приложение. Мы собираемся оставить сервер работать в этом консольном окне. Позже, после того как вы напишете код приложения и оно будет запущено в нашем браузере, у нас будет возможность воспользоваться этим консольным окном для отслеживания входящих запросов. Когда наступит время выключить ваше приложение, можно будет, находясь в этом окне, нажать Ctrl+C чтобы остановить WEBrick (не делайте этого сейчас, через минуту мы именно этим приложением и воспользуемся).
Итак, у нас есть запущенное новое приложение, но в нем вообще нет нашего кода. Давайте исправим эту ситуацию.
2.2. Привет, Rails!
Ничего не поделаешь, для испытания новой системы придется написать программу Hello, World! Начнем с создания простейшего приложения, отправляющего на браузер наше радостное приветствие. Как только оно заработает, мы украсим его показом текущего времени и ссылками.
В главе 3 «Архитектура Rails-приложений» мы выясним, что Rails относится к среде Модель—Представление—Контроллер (Model—View—Controller). Rails получает входящие запросы от браузера, декодирует запрос для поиска контроллера и вызывает в контроллере метод, который называется действием. Затем контроллер вызывает соответствующее представление, отображающее результаты на экране пользователя. Для нас Rails хороша тем, что берет на себя управление большей частью внутренних каналов, связывающих все эти действия. Чтобы создать простейшее приложение Hello, World!, нам нужен код для контроллера и представления и нужен связывающий их маршрут. Для модели нам код не нужен, поскольку мы не имеем дела с данными. Начнем с контроллера.
Затем контроллер вызовет конкретное представление, чтобы пользователь мог увидеть результаты.
Рис. 2.1. Только что созданное Rails-приложение
Аналогично тому, как для создания нового Rails-приложения мы воспользовались командой rails, для создания нового контроллера для нашего проекта мы можем также воспользоваться генерирующим сценарием. Он вызывается командой rails generate. Итак, для создания контроллера под названием say нужно убедиться, что мы находимся в каталоге demo, и запустить команду, передав ей имя создаваемого контроллера и имена действий, предназначаемых для поддержки этого контроллера:
demo> rails generate controller Say hello goodbye
create app/controllers/say_controller.rb
route get "say/goodbye"
route get "say/hello"
invoke erb
create app/views/say
create app/views/say/hello.html.erb
create app/views/say/goodbye.html.erb
invoke test_unit
create test/functional/say_controller_test.rb
invoke helper
create app/helpers/say_helper.rb
invoke test_unit
create test/unit/helpers/say_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/say.js.coffee
invoke scss
create app/assets/stylesheets/say.css.scss
Команда rails generate ведет протокол проверяемых файлов и каталогов, отмечая добавление новых Ruby-сценариев или каталогов к вашему приложению. На данный момент нас интересует один из этих сценариев, а еще через минуту заинтересуют и файлы .html.erb.
Сначала нужно найти исходный файл контроллера. Он находится в файле app/controllers/say_controller.rb. Посмотрим на его содержимое:
rails31/work/demo1/app/controllers/say_controller.rb
class SayController < ApplicationController
def hello
end
def goodbye
end
end
Довольно лаконично, не правда ли? SayController — это класс, наследуемый из ApplicationController, поэтому он автоматически перенимает все исходное поведение контроллера. Что этот код должен делать? Пока он не делает ничего, у нас просто есть пустой метод действия по имени hello. Чтобы понять, почему он так назван, нужно посмотреть, как Rails обрабатывает запросы.
Rails и запросы URL-адресов
В представлении своих пользователей Rails-приложение, как, собственно, и любое другое веб-приложение, связано с URL-адресом. Когда браузеру указывается этот URL-адрес, происходит обращение к коду приложения, который генерирует для вас ответ.
Давайте попробуем прямо сейчас. Перейдите в окне браузера на URL-адрес http://localhost:3000/say/hello. (Заметьте, что в разрабатываемом приложении в начале пути отсутствует какая-либо строка, указывающая на само приложение, — мы обращаемся непосредственно к контроллеру.) Вы увидите на экране окно, похожее на то, которое показано на рис. 2.2.
Рис. 2.2. Шаблон, подготовленный для нашего заполнения
Наше первое действие
На данный момент мы можем увидеть не только ответ на вопрос, подключен ли URL-адрес к нашему контроллеру, но также и то, что Rails указывает путь к нашему следующему шагу, а именно — сообщению Rails о том, что отобразить на экране. Здесь в игру вступают представления. Вспомните: когда мы запустили сценарий для создания нового контроллера, эта команда добавила к нашему приложению шесть файлов и новый каталог. В этом каталоге содержатся файлы шаблонов для представлений контроллера. В нашем случае мы создали контроллер, названный say, следовательно, представления будут находиться в каталоге app/views/say.
По умолчанию Rails ищет шаблоны в файле с тем же именем, что и у действия, занимающегося его обработкой. В нашем случае это означает, что нам нужно заменить файл по имени hello.html.erb в каталоге app/views/say. (Почему .html.erb? Совсем скоро мы все объясним.) А теперь давайте просто поместим в файл элементарный код HTML:
rails31/work/demo1/app/views/say/hello.html.erb
<h1>Привет от Rails!</h1>
Сохраните файл hello.html.erb и обновите окно браузера. Вы увидите в нем наше приветствие:
Всего мы просмотрели два файла в нашем дереве Rails-приложения. Мы смотрели на контроллер, и мы изменили шаблон отображения страницы в браузере.
Эти файлы находятся в стандартных местах иерархической структуры Rails: контроллеры размещаются в каталоге app/controllers, а представления — в подкаталогах, принадлежащих каталогу app/views. Стандартные места для контроллеров и представлений показаны на рис. 2.3.
Рис. 2.3. Стандартные места для контроллеров и представлений
Придание динамичности
Пока у нашего Rails-приложения довольно скучный вид — оно просто отображает статичную страницу. Для придания ему динамичности давайте заставим его показывать текущее время при каждом отображении страницы.
Для этого необходимо внести изменения в файл шаблона в представлении: теперь в него нужно включить время в виде строки. При этом возникает два вопроса. Во-первых, как добавляется динамическое содержимое к шаблону? И во-вторых, откуда мы возьмем это время?
Динамическое содержимое
В Rails есть множество способов создания динамических шаблонов. Наиболее распространенный из них, которым мы здесь воспользуемся, заключается во вставке кода Ruby непосредственно в шаблон. Именно поэтому наш файл шаблона называется hello.html.erb — суффикс .html.erb предписывает Rails расширить содержимое файла с помощью системы, которая называется ERB.
ERB — это фильтр, устанавливаемый как часть Rails, который берет файл .erb и выдает преобразованную версию. Выходной файл в Rails чаще всего имеет формат HTML, но вообще-то может иметь какой угодно формат. Обычно содержимое пропускается через фильтр без изменений. А содержимое, находящееся между группами символов <%= и %>, интерпретируется как Ruby-код, который выполняется. В результате этого выполнения содержимое превращается в строку, значение которой подставляется в файл вместо последовательности <%=…%>. Например, внесите в hello.html.erb изменения, позволяющие вывести текущее время:
rails31/work/demo2/app/views/say/hello.html.erb
<h1>Привет от Rails!</h1>
После обновления окна нашего браузера мы увидим время, отображенное с использованием стандартного формата Ruby14:
Обратите внимание: при щелчке на кнопке браузера Обновить (Refresh) время обновляется при каждом выводе страницы. Это похоже на настоящую генерацию динамического содержимого.
Добавление времени
Исходная задача заключалась в демонстрации времени пользователям нашего приложения. Теперь мы знаем, как заставить приложение выводить динамические данные. Но нужно решить еще одну задачу: откуда брать время?
Мы показали, что подход со вставкой вызова Ruby-метода Time.now() в нашем шаблоне hello.html.erb работает. При каждом обращении к этой странице пользователь будет видеть текущее время, вставленное в тело ответа. Для нашего простейшего приложения этого может быть вполне достаточно. Но нам все-таки хочется сделать все немного по-другому. Мы переместим определение отображаемого значения текущего времени в контроллер, а представлению оставим простую работу по его отображению. Для этого мы изменим метод действия в контроллере, чтобы присвоить значение времени переменной экземпляра под названием @time:
rails31/work/demo3/app/controllers/say_controller.rb
class SayController < ApplicationController
def hello
end
def goodbye
end
end
В шаблоне .html.erb мы воспользуемся этой переменной экземпляра, чтобы подставить время в выводимые данные:
rails31/work/demo3/app/views/say/hello.html.erb
<h1>Привет от Rails!</h1>
<p>
</p>
После обновления окна браузера мы опять увидим текущее время, что свидетельствует об успешной связи между контроллером и представлением.
Упрощение разработки
В процессе той разработки, которой мы только что занимались, уже можно было кое-что заметить. Когда к уже работающему приложению добавлялся какой-нибудь код, его не приходилось перезапускать. Все необходимое делалось без нашего участия в фоновом режиме. И каждое вносимое нами изменение становилось доступным, как только мы обращались к приложению через браузер. Благодаря чему все это происходило?
Оказывается, благодаря достаточно разумному поведению диспетчера Rails. В режиме разработки (в отличие от режимов тестирования или эксплуатации) при поступлении нового запроса диспетчер автоматически перезагружает исходные файлы приложения. Таким образом, при редактировании приложения диспетчер обеспечивает запуск самой последней версии. Для режима разработки это очень хорошее качество.
Тем не менее за такую гибкость поведения приходится платить — она приводит к небольшой паузе между вводом URL-адреса и откликом приложения, которая вызвана тем, что диспетчер осуществляет перезагрузку. Для разработки это вполне разумная цена, но при эксплуатации готового приложения такой режим будет неприемлем. Поэтому перед развертыванием приложения этот режим отключается (см. главу 16 «Задача Л: развертывание и эксплуатация»).
Зачем нам понадобились дополнительные хлопоты по установке отображаемого времени в контроллере с последующим использованием этого времени в представлении? Хороший вопрос. В данном приложении нет практически никакой разницы, но, помещая логику работы приложения из представления в контроллер, мы получаем некоторые преимущества. Например, в будущем может потребоваться усовершенствовать наше приложение, чтобы оно поддерживало работу пользователей во многих странах. В таком случает понадобится локализовать отображение времени, выбрав время, соответствующее часовому поясу пользователей. Для этого может понадобиться достаточно большой объем кода на уровне приложения, и, возможно, его вставка на уровне представления окажется неприемлемой. Устанавливая значение отображаемого времени в контроллере, мы придаем своему приложению дополнительную гибкость — теперь мы можем изменять часовой пояс в контроллере, и тогда уже не придется обновлять каждое представление, в котором используется этот объект времени. Время — это данные, которыми контроллер должен снабжать представление. При согласовании моделей вам будет представлено намного больше подобных примеров.
Итак, чего мы добились
Рассмотрим вкратце работу созданного приложения.
1. Пользователь переходит к работе с приложением, воспользовавшись в нашем случае локальным URL-адресом http://localhost:3000/say/hello.
2. Затем Rails проводит сравнение со схемой маршрута, которая предварительно разбивается на две части.
Фрагмент say воспринимается как имя контроллера, поэтому Rails создает новый экземпляр Ruby-класса SayController (который находит в файле app/controllers/say_controller.rb).
3. Следующий фрагмент URL, hello, рассматривается как идентификатор действия. Rails вызывает в контроллере метод с таким же названием. Этот метод, определяющий действие, создает новый объект Time, содержащий текущее время, и убирает его содержимое в переменную экземпляра @time.
4. Rails ищет шаблон, чтобы отобразить результат. Для этого просматривается каталог app/views, в котором идет поиск подкаталога с именем, аналогичным имени контроллера (say), а в этом подкаталоге ищется файл, названный по имени действия (hello.html.erb).
5. Rails обрабатывает этот файл с использованием системы работы с шаблонами ERB, исполняя все Ruby-вставки и подставляя значения, установленные контроллером.
6. Результат возвращается браузеру, и Rails завершает обработку данного запроса.
Но это еще не все. Rails предоставляет вам массу возможностей для внесения изменений в основную последовательность выполняемых действий (и мы отчасти этим воспользуемся). В данных условиях наша история является типичным примером использования соглашения по конфигурации, одной из основ философии Rails. Благодаря тому, что Rails-приложениям предоставляются удобные исходные настройки, а при их разработке применяются определенные соглашения по составлению URL-адреса или по файлу, в который помещается определение контроллера, а также по имени используемого класса и именам методов, Rails-приложения создаются, как правило, с незначительным использованием или вовсе без использования внешних конфигурационных настроек, что позволяет связывать их в единое целое вполне естественным образом.
2.3. Соединение страниц
Веб-приложения, состоящие из одной страницы, встречаются довольно редко. Давайте посмотрим, как к нашему приложению с приветствием можно добавить еще один впечатляющий пример веб-дизайна.
Обычно каждой странице приложения соответствует отдельное представление. В нашем случае для обработки страницы также будет использован новый метод действия (хотя, далее в данной книге будет показано, что так бывает не всегда). Для обоих действий будет использован один и тот же контроллер. Вообще-то, так делать не обязательно, но каких-то причин, вынуждающих использовать новый контроллер, пока нет.
Для этого контроллера уже было определено действие goodbye, поэтому остается только создать новый шаблон в каталоге app/views/say. На этот раз он называется goodbye.html.erb, поскольку по умолчанию шаблоны получают имена тех действий, которые с ними связаны.
rails31/work/demo4/app/views/say/goodbye.html.erb
<h1>До свидания!</h1>
<p>
Очень приятно, что вы нас навестили.
</p>
Обратимся еще раз к нашему уже испытанному браузеру, но теперь уже укажем на новое действие, воспользовавшись URL http://localhost:3000/say/goodbye. Должна появиться картинка, похожая на эту:
Теперь нам нужно связать эти два экрана. Мы поместим на страницу hello ссылку, которая приведет нас на страницу goodbye, и наоборот. В настоящем приложении для этого, скорее всего, понадобится создать соответствующие кнопки, но сейчас мы воспользуемся простыми гиперссылками.
Нам уже известно, что в Rails используется соглашение о синтаксическом разборе URL-адреса с целью получения целевого контроллера и имеющиеся внутри него действия. Поэтому проще всего будет воспользоваться этим URL-соглашением для наших ссылок.
В файле hello.html.erb будет содержаться следующий код:
...
<p>
Сказать <a href="/say/goodbye">до свиданья</a>!
</p>
...
А в файле goodbye.html.erb будет указатель на обратный путь:
...
<p>
Сказать <a href="/say/hello">привет</a>!
</p>
...
Конечно, все это будет работать, но сам по себе этот код слишком несовершенен. Если придется перемещать наше приложение в другое место на веб-сервере, URL-адреса уже не будут указывать на правильное место. К тому же в наш код также закладываются предположения об используемом в Rails формате URL-адреса, который в будущих версиях Rails может измениться.
К счастью, мы можем обойтись без всякого риска. Rails поставляется с целым пакетом вспомогательных методов, которые могут использоваться в шаблонах представлений. В данном случае мы воспользуемся вспомогательным методом link_to(), создающим гиперссылку на действие. (Метод link_to() способен на большее, но пока ограничимся только этой возможностью.) При использовании link_to(), hello.html.erb приобретает следующий вид:
rails31/work/demo5/app/views/say/hello.html.erb
<h1>Привет от Rails!</h1>
<p>
Сейчас <%= @time %>
</p>
Здесь мы видим вызов метода link_to() внутри ERB-последовательности <%=…%>. За счет него создается ссылка на URL-адрес, который вызовет действие goodbye(). Первым аргументом вызова link_to() является текст, отображаемый в гиперссылке, а второй аргумент заставляет Rails сгенерировать ссылку на действие goodbye.
Давайте уделим пару минут рассмотрению порядка генерации ссылки. Мы написали следующий код:
link_to "до свидания", say_goodbye_path
Начнем с того, что link_to — это вызов метода. (В Rails методы, облегчающие написание шаблонов, называются помощниками.) Если вам приходилось работать с такими языками, как Java, отсутствие обязательных круглых скобок вокруг аргументов метода может вызвать удивление. Но если они вам нравятся, их всегда можно добавить.
Фрагмент say_goodbye_path является заранее вычисленным значением, которое Rails делает доступным для представлений приложения. Этот фрагмент превращается в путь /say/goodbye. Со временем вы увидите, что Rails предоставляет возможность дать имена всем маршрутам, которые будут использоваться в вашем приложении.
А теперь вернемся к приложению. Если направить браузер на открытие нашей страницы hello, то на ней будет ссылка на страницу goodbye:
Соответствующие изменения могут быть сделаны и в файле goodbye.html.erb, чтобы появилась ссылка на начальную страницу hello:
rails31/work/demo5/app/views/say/goodbye.html.erb
<h1>До свиданья!</h1>
<p>
Очень приятно, что вы нас навестили.
</p>
Вот мы и завершили разработку нашего пробного приложения, проверив тем самым работоспособность нашей установки Rails. После краткого резюме наступит время перехода к созданию настоящего приложения.
2.4. Наши достижения
Мы создали пробное приложение, увидев при этом:
× как создается новое Rails-приложение и как создается новый контроллер этого приложения;
× как в контроллере создается динамическое содержимое и как оно отображается через шаблон представления;
× как страницы соединяются друг с другом.
Это послужит неплохой стартовой площадкой, для создания которой не пришлось тратить слишком много времени или усилий. Этот опыт будет наращиваться при переходе к следующей главе и создании нового, более крупного приложения.
Чем заняться на досуге
Поэкспериментируйте со следующими выражениями:
• Сложение: <%= 1+2 %>
• Объединение: <%= "cow" + "boy" %>
• Время через час: <%= 1.hour.from_now %>
Вызов следующего Ruby-метода возвращает список всех файлов в текущем каталоге:
@files = Dir.glob('*')
Воспользуйтесь им для задания значения переменной экземпляра в действии контроллера, а затем напишите соответствующий шаблон, выводящий в браузере список имен файлов.
Подсказка: просканировать коллекцию можно с помощью следующего кода:
<% for file in @files %>
file name is: <%= file %>
<% end %>
Для формирования списка можно воспользоваться тегом <ul>.
(Подсказки можно найти по адресу http://www.pragprog.com/wikis/wiki/RailsPlay Time.)
Ликвидация последствий
Если вы, следуя за повествованием, набирали код, то, возможно, приложение все еще работает на вашем компьютере. Когда приблизительно через десять страниц мы приступим к программированию нашего следующего приложения, при его первом запуске возникнет конфликт, поскольку для общения с браузером оно также попытается воспользоваться компьютерным портом 3000. Сейчас как раз настало время остановить текущее приложение, нажав комбинацию клавиш Ctrl+C в том окне, которое использовалось для его запуска.
А теперь перейдем к обзору Rails.
Глава 3. Архитектура Rails-приложений
Основные темы:
Одной из существенных особенностей Rails является то, что она накладывает весьма серьезные ограничения на структурирование веб-приложений. Как ни странно, эти ограничения упрощают создание приложений, причем существенно. Посмотрим, почему так происходит.
3.1. Модели, представления и контроллеры
В далеком 1979 году Трюгве Реенскауг (Trygve Reenskaug) придумал новую архитектуру для разработки интерактивных приложений. По его замыслу приложения разбиваются на компоненты трех типов: модели, представления и контроллеры.
Модель отвечает за поддержку состояния приложения. Иногда это состояние является кратковременным, продолжающимся только на время нескольких взаимодействий с пользователем. А иногда состояние является постоянным и сохраняется вне приложения, чаще всего в базе данных.
Модель — это не просто данные; в ней прописаны все бизнес-правила, применяемые к этим данным. К примеру, если скидка не должна применяться к заказам стоимостью менее 20 долларов, моделью будут предписаны соответствующие ограничения. И в этом есть свой определенный смысл. Помещая реализацию бизнес-правил в модель, мы гарантируем, что ничто иное в приложении не может сделать наши данные некорректными. Модель работает и сторожем, и хранителем данных.
Представление отвечает за формирование пользовательского интерфейса, который обычно основан на данных модели. Например, интернет-магазин должен иметь перечень товаров для отображения на экране каталога. Этот перечень будет доступен через модель, но получать его у модели и форматировать для показа конечному пользователю будет представление. Хотя представление может предлагать пользователю различные способы ввода данных, оно никогда не занимается их непосредственной обработкой. Работа представления завершается, как только данные будут отображены на экране. Доступ к одним и тем же данным модели, зачастую с разными целями, может иметь множество представлений. В интернет-магазине может быть представление, отображающее информацию о товаре на странице каталога, и другой набор представлений, используемых администраторами для добавления товаров или редактирования сведений о них.
Контроллеры организуют работу приложения. Они воспринимают события внешнего мира (обычно ввод данных пользователем), взаимодействуют с моделью и отображают соответствующее представление для пользователя.
Этот триумвират — модель, представление и контроллер — формирует архитектуру, известную как MVC (Model—View—Controller — Модель—Представление-Контроллер). Взаимодействие этих трех элементов концепции показано на рис. 3.1.
Рис. 3.1. Архитектура Модель—Представление—Контроллер
Сначала архитектура MVC предназначалась для обычных GUI-приложений, при создании которых разработчики поняли, что распределение ролей приводит к существенному уменьшению взаимных увязок, что в свою очередь облегчает написание и сопровождение программного кода. Каждое понятие или действие четко определялось только в одном, хорошо известном месте. Использование MVC напоминало строительство небоскреба при наличии уже готового каркаса: когда есть готовая структура, навесить на нее все остальные элементы намного проще. В процессе разработки нашего приложения мы часто будем пользоваться возможностями Rails по генерации для нашего приложения временных платформ (scaffold
