Несмотря на относительную молодость (чуть больше двух лет), проект 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 позволяет действительно быстро создавать гибкие и легко масштабируемые приложения, которые могут обращаться к БД в том виде, в каком это необходимо в каждом конкретном случае. А классическая трехзвенная архитектура дает широкие возможности представления информации в системах, использующих для доступа к данным веб-интерфейсы.

3028