Несмотря на относительную молодость (чуть больше двух лет), проект Ruby on Rails имеет уже довольно много поклонников среди разработчиков веб-приложений.
Что же так притягивает к нему программистов?
Судя по отзывам на форумах и в блогах, большинство из тех, кто использовал Ruby on Rails, сходятся во мнении: среда проста, понятна и позволяет создавать достаточно сложные и масштабные приложения в несколько раз быстрее, чем любые другие средства.
Что же такого особенного в этом проекте? Какие факторы позволяют упростить и ускорить разработку?
Собственно, их два: во-первых, язык Ruby, во-вторых, сама идея среды Rails.
История Ruby и Rails
В 1995 г. японский разработчик свободного ПО Юкихиро Мацумото (также известный как Matz) придумал свой собственный язык программирования Ruby и написал для него интерпретатор. В одном из интервью Matz сказал: «Мне был нужен «скриптовый» язык, более мощный, чем Perl, и более объектно-ориентированный, чем Python. Поэтому я решил создать свой собственный язык программирования».
Название Ruby указывает на связь с языком Perl, из которого были взяты многие особенности синтаксиса и семантики (англ. pearl — жемчужина, ruby — рубин).
Кроссплатформная реализация интерпретатора языка распространяется с открытыми исходными текстами, возможностью копирования и модификации. Последняя на момент написания статьи версия 1.8.5 вышла 28 августа 2006 г.
Ruby — интерпретируемый язык высокого уровня для быстрого и удобного объектно-ориентированного программирования. Он обладает независимой от операционной системы реализацией многопоточности, строгой динамической типизацией, «сборщиком мусора» и многими другими возможностями. Ruby близок по особенностям синтаксиса к языкам Perl и Eiffel, по объектно-ориентированному подходу — к Smalltalk. Некоторые черты языка взяты из Python, LISP, Dylan и CLU.
Ruby on Rails (RoR или просто Rails) — это разработанная сотрудником компании «37signals» Давидом Хайнмайером Ханссоном (David Heinemeier Hansson) среда для построения веб-приложений. Rails написана на Ruby и следует архитектуре MVC (Model—View—Controller, модель—представление—контроллер). Одно из ее главных преимуществ в том, что эта среда не разрабатывалась с нуля, а была выделена из успешно работающего интернет-приложения Basecamp (http://basecamphq.com) — программы для управления проектами. Первая версия Rails появилась в июле 2004 г.
Среда уже была опробована на действующем проекте, и не требовалось длительного и сложного тестирования, так как Ruby on Rails изначально представляла собой часть заведомо работающей системы. Оставалось лишь адаптировать ее к самостоятельному существованию. Rails — открытая среда, что и стало залогом ее постоянного совершенствования и быстрого распространения.
Итак, в основе Rails лежат два компонента, определившие ее успех, — это объектно-ориентированный язык Ruby и трехзвенная архитектура MVC.
Объектная модель Ruby
Язык Ruby полностью объектно-ориентированный, в нем все без исключения является объектом: классы, классы классов, данные, константы True и False и т.д. Но это не мешает Ruby-разработчикам использовать существующие парадигмы, программируя процедурно, объектно-ориентированно или же функционально.
Этот язык бестиповый в отличие, например, от Java или C++. Переменные Ruby не имеют типов и не являются объектами — они лишь содержат ссылку на них. Тип переменной определяется значением атрибута.
Ruby поддерживает мета-программирование, что безусловно определило успех самого языка и созданной на его основе платформы Ruby on Rails.
Архитектура MVC
Какова же инфраструктура Rails? В основе ее заложена реализация трехзвенной архитектуры, или, как ее еще называют, MVC. То есть в Ruby on Rails существует четкое разделение уровня данных, бизнес-логики и представления данных пользователю.
Как видно из названия, эта архитектура характеризуется тремя основными элементами:
- модель - ядро приложения. Реализует все основные алгоритмы, обрабатывает полученные от контроллера данные и формирует соответствующее представление;
- контроллер - принимает входные данные от пользователя и, преобразовав их, передает в модель;
- представление - средство отображения информации, полученных данных о модели и ее состоянии.
В классическом варианте (рис. 1) эта идея применяется практически во всех настольных приложениях, работающих с базами данных.
Рис. 1. Классическая модель трехзвенной архитектуры |
В веб-приложениях она была реализована не сразу. В эпоху CGI-интерфейсов не существовало разделения бизнес-логики и представлений и способ отображения данных для пользователя частенько «зашивался» в исполняемый модуль вместе с алгоритмами обработки данных. Это было не очень удобно и значительно затрудняло разработку приложения, а также его последующую модификацию и масштабирование.
Затем в разное время стали появляться всевозможные средства, позволяющие реализовать в интернет-приложениях трехуровневую модель: библиотеки MIDAS для разработчиков на платформе Borland, среда Sturts на основе шаблона проектирования (pattern) MVC для Java-разработчиков и т.д.
Эта же идея реализована и в Rails, но в несколько ином виде. RoR состоит из двух логических компонентов — ActiveRecord и ActionPack.
Первая составляющая реализует именно уровень представления данных — модель.
ActionPack объединяет в себе два других уровня архитектуры MVC — контроллер и представление.
В целом архитектура MVC в Ruby on Rails выглядит, как показано на рис. 2.
Рис. 2. Архитектура MVC в Ruby on Rails |
Рассмотрим каждый элемент более подробно.
ActiveRecord
ActiveRecord по сути решает задачу представления базы данных в виде объектов. При этом создается устойчивая модель предметной области, в которой объединяются сами данные и способы управления ими. Отображение предметной области на реляционную модель происходит следующим образом: таблица представляется классом, строки таблицы — объектами, поля — атрибутами объекта.
Возьмем для примера таблицу Persons с полями Name, LastName, Position. Запустив один-единственный Ruby-скрипт, мы получим класс Person с тремя вышеописанными полями и методами, позволяющими оперировать записями БД:
ruby script/generate model User
Класс будет объявлен в соответствующем файле Person.rb. Rails именует класс автоматически, исходя из того, что название таблицы должно задаваться во множественном числе. Поэтому класс имеет то же имя, но в единственном числе. Хотя, если ваша таблица называется по-другому, вы всегда можете отойти от умолчаний и переопределить названия.
Объявление класса в созданном файле будет выглядеть примерно так:
class Person < ActiveRecord::Base
Теперь мы можем объявлять объекты этого класса:
person = Person.new (:name => «Василий», :lastname => «Иванов», :Position => «программист»)
То же можно выполнить и несколько иначе, более привычным способом:
person = person.new person.name = "Василий" person.lastname = "Иванов" person.position = "программист"
Что касается методов создаваемых классов, то реализованы они довольно просто и синтаксис их очень близок к естественному языку. Методов достаточно много, что позволяет полностью управлять таблицами БД, отдельными записями и группами записей, столбцами и их значениями и т.д., а также создавать, удалять, изменять записи и конечно же осуществлять поиск, как с помощью явного SQL-выражения, так и с использованием атрибутов метода Find.
ActionPack
Вторая составляющая среды Rails, ActionPack, в свою очередь содержит две части — ApplicationController (реализация бизнес-логики) и ActionView (механизм представлений).
Но начнем мы с последнего, с представлений. Здесь все не слишком сложно. Представления — это шаблоны страниц, использующие RHTML (HTML со встроенным Ruby) или RXML (XML, сгенерированный с помощью Ruby).
Представления должны сначала пройти процесс рендеринга (rendering), когда все Ruby-выражения на странице шаблона заменяются соответствующими значениями — данными из БД. В результате мы получим HTML- или XML-документ, готовый к отображению в браузере.
Простейший пример представления (назовем его list.rhtml) для нашей условной БД Persons может выглядеть так:
Список сотрудников
<% for person in @persons %> Фамилия: <%= person.lastname>
Имя: <%= person.name %>
Должность: <%= person.position %><% end %>
Как видно из примера, при рендеринге этого шаблона будут перебраны и выданы по полям все записи БД Persons.
По отдельности модель и представления не имеют смысла. Модель может обеспечивать доступ к данным и средства управления ими, а представление определяет способ выдачи данных на экране. Единственное, что может объединить эти составляющие в целостную архитектуру, — это контроллер. Именно этот элемент Rails определяет, как обрабатывается каждое конкретное представление и как оно связано с моделью.
Собственно ApplicationController — это базовый, абстрактный класс, на основе которого создаются контроллеры, определяющие принципы передачи информации от представления к модели и обратно. Такие работающие контроллеры относятся к классу ActionController.
Контроллеры функционируют в связке с подсистемой маршрутизации запросов, в оригинале называемой просто routing. Ее задача — определить контроллер и действие (Action), используемые для обработки представления, а также дополнительные условия и параметры. Вся эта информация передается через URL.
Так, например, из строки .../person/list/ очевидно, что для класса PersonController будет вызвано действие list, которое произведет рендеринг шаблона list.rhtml.
Сам класс PersonController и его действия определяются так:
class PersonController < ActionController::Base def list @persons = Person.find(:all) end end
Это лишь самый простой пример объявления контроллера. На практике можно переадресовывать действия, выполнять в процессе рендеринга сложные запросы, учитывать многочисленные параметры, также передаваемые контроллеру в адресной строке.
Плюсы и минусы Ruby on Rails
Разумеется, реализация модели MVC — не единственная причина, по которой Ruby on Rails привлекает все больше и больше последователей. Есть ряд идеологических объяснений простоты и удобства использования этой среды.
Во-первых, Ruby on Rails написана на Ruby. Значит, на каждом этапе разработки используется один и тот же язык, чем сильно упрощается процесс написания. При этом нужно помнить, что Ruby предлагает легко читаемую нотацию для определения семантики приложений.
Во-вторых, в среде Rails применяется принцип повторного использования кода (по-английски звучит как «Don?t Repeat Yourself»), т.е. программа или программный модуль частично либо полностью должны составляться из написанных ранее компонентов и/или частей другой системы.
Ну и наконец, среда Ruby on Rails основывается на принципе соглашения о конфигурации. Rails не использует конфигурационные файлы, а берет всю необходимую информацию из кода приложений и базы данных. Это позволяет обойтись без компиляции и сразу видеть результат разработки.
Есть ли у Ruby on Rails минусы?
Безусловно. Собственно, рельсы они и есть рельсы: скорость можно развить приличную, но выбирать дорогу не приходится. Действительно, за счет массы встроенных механизмов и тщательно продуманной модели можно создавать приложения намного быстрее, чем иными средствами. Однако при этом приходится жертвовать гибкостью разработки. Заметьте, гибкостью не приложений, а именно процесса их создания.
Ну и если уж совсем критически оценивать ситуацию, то к минусам можно причислить существующие в настоящее время сложности с хостингом.
На сегодняшний день на официальном сайте Ruby on Rails (http://rubyonrails.org) приводится внушительный список серверов, поддерживающих эту технологию. Но российских хостеров в этом списке нет вообще. Четыре российские компании, предлагающие хостинг сайтов, использующих Ruby on Rails, указаны на русскоязычном ресурсе (http://rubyonrails.ru).
Ruby on Rails может работать с любыми серверами, поддерживающими технологию FastCGI. Из самых популярных стоит назвать Apache и Lighttpd.
В качестве сервера базы данных Ruby on Rails поддерживает MySQL, PostgreSQL, SQLite, IBM DB2, Oracle и Microsoft SQL Server, а также встраиваемую СУБД SQLite.
Кроме того, провайдер должен вовремя обновлять пакеты Ruby on Rails: среда постоянно развивается и обновления появляются регулярно.
Именно поэтому поддержка Ruby on Rails большинством провайдеров — это всего лишь вопрос времени, причем не самого долгого.
В остальном же Ruby on Rails позволяет действительно быстро создавать гибкие и легко масштабируемые приложения, которые могут обращаться к БД в том виде, в каком это необходимо в каждом конкретном случае. А классическая трехзвенная архитектура дает широкие возможности представления информации в системах, использующих для доступа к данным веб-интерфейсы.