Ruby on Rails – это инструмент разработки, который предоставляет веб-разработчикам фреймворк, обеспечивающий структуру для всего кода, который они пишут. Платформа Rails помогает разработчикам создавать веб-сайты и приложения, поскольку она отделяет и упрощает общие повторяющиеся задачи.
Rails написан на Ruby, языке программирования, который также используется вместе с Rails. Ruby для Rails – как PHP для Symfony и Zend, а Python для Django. Привлекательность Ruby для разработчиков заключается в элегантности и краткости языка.
Особенности
Одним из ключевых принципов разработки Ruby on Rails (далее "Rails") является программирование по соглашениям. Это означает, что программисту не нужно тратить много времени на настройку файлов, чтобы приступить к работе. Rails поставляется с набором соглашений, которые помогают ускорить разработку.
Другой особенностью Rails является акцент на RESTful-дизайне приложений. REST (Transfer State Transfer) – это стиль архитектуры программного обеспечения, основанный на отношениях клиент-сервер. Он поощряет логическую структуру в приложениях, что означает, что они могут быть легко представлены как API (интерфейс прикладного программирования).
С точки зрения управления проектами сообщество Ruby on Rails отстаивает гибкую веб-разработку – метод итеративной разработки, который поощряет совместный и гибкий подход, особенно хорошо подходящий для разработки проектов с быстро меняющимися требованиями.
Преимущества и недостатки
Плюсы использования Ruby on Rails:
- Процесс программирования намного быстрее, чем с другими средами и языками, отчасти из-за объектно-ориентированной природы Ruby и обширной коллекции открытого исходного кода, доступного в сообществе Rails;
- Соглашения Rails также позволяют разработчикам легко переключаться между различными проектами Rails, так как каждый проект будет следовать одной и той же структуре и методам кодирования;
- Rails хорош для быстрой разработки приложений (RAD), поскольку этот фреймворк позволяет легко приспосабливаться к любым изменениям;
- Код на Ruby очень читабелен и в основном самодокументирован. Это повышает продуктивность, так как нет необходимости писать отдельную документацию для других разработчиков, взявшихся за ваш проект;
- Rails уделяет большое внимание тестированию и имеет хорошие тестовые фреймворки;
- Rails и большинство его библиотек имеют открытый исходный код. Поэтому, в отличие от других коммерческих сред разработки, вам не придется тратить деньги на лицензионные соглашения.
Потенциальные проблемы и ограничения:
- Не все веб-хосты могут поддерживать Rails. Это прежде всего объясняется тем, что он может быть более ресурсоемким, чем PHP, что отпугивает низкоуровневых провайдеров совместного хостинга. Тем не менее, это ни в коем случае не является полной закономерностью. Конечно же, существуют дружественные к Rails хосты, например, Heroku и EngineYard. Кроме того, вы можете разместить свое приложение Rails на виртуальном частном сервере (VPS) с Amazon EC2, Rackspace или Linode. После этого вы получите полный контроль над сервером и сможете выделить достаточно ресурсов для своего приложения;
- Java и PHP более широко используются, и на этих языках гораздо больше разработчиков. Количество разработчиков Ruby растет из года в год, так как все больше людей переходят на него с других языков программирования. Одним из основных различий между Ruby и другими сообществами является количество открытого исходного кода (гемов), который является общедоступным. На момент написания этой статьи существует 63 711 гемов, которые можно использовать для улучшения своего приложения;
- Производительность и масштабы. Одно время были опасения, что приложения на Rails не такие быстрые, как Java или C. И хотя это утверждение верно, для большинства приложений существующие различия в быстродействии будут практически незаметными. Есть множество известных организаций, которые используют Rails для питания своих сайтов, включая AirBnB, Yellow Pages, Groupon, Channel 5 и Gov.uk. Существует также возможность запуска приложения под JRuby, что даст вам такие же параметры производительности, как и у Java.
Простота структуры
Хотя большинство разработчиков согласны с тем, что Ruby удобен, некоторые считают его слишком удобным. Они беспокоятся о том, что Ruby предоставляет слишком много свободы, которая иногда может становиться причиной больших проблем. Это можно проиллюстрировать несколькими “обезьянскими патчами” (подменой методов и атрибутов):
"1".to_i
#=> 1
class String
def to_i
raise 'foobar'
end
end
"1".to_i
#=> RuntimeError: foobar
Именно так просто: всего пять строк кода, с помощью которых мы взяли существующий класс и изменили его поведение. Ничто в Ruby не является неприкасаемым – даже строка. Конкретно эту ошибку легко заметить, но все может стать гораздо более опасным:
class String
def to_i
self.to_f - 1.13
end
end
"2".to_i
#=> 0.8700000000000001
Вот так просто мы внедрили ошибку в класс String, которая может быть скрыта слоями сложного кода.
Итак, вы можете подумать: абсолютно любой человек может испортить структуру моего приложения? И хотя наведенные примеры выглядят действительно устрашающе – на самом деле это не так. За годы использования Ruby у большинства разработчиков возникает ровно ноль проблем с подобными вещами. Такая ситуация может показаться нелогичной и слишком рисковой, но то же самое происходит с автомобилями на скорости в 80 км в час, мчащихся в противоположных направлениях, разделенных только тонкой белой линией посреди дороги. На практике же оба метода работают превосходно.
Полезные особенности Ruby
Так как при работе в Rails разработчику придется иметь дело с Ruby, будет неплохо узнать несколько полезных возможностей этого динамического языка программирования.
Динамическая типизация
В статически типизированных языках имеются очень хорошие возможности, такие как тестирование во время компиляции и поддержка IDE. Тем не менее динамическая типизация очень помогает на ранних этапах проектов и сглаживает изменения, особенно в начале и середине разработки.
Очень приятно, когда тебе не нужно создавать формальный интерфейс для реализации новых объектов, просто чтобы ты мог потом легко поменять этот класс на другой.
Неявная типизация
Это фактически просто расширение динамического набора текста. В Ruby методы, которые как ожидаются, смогут работать с объектами String, не проверяют is_a? (String). Они проверяют, является ли объект response_to? (: To_str), а затем вызывает to_str для объекта, если это так. Точно так же объекты, которые представляют Paths в Ruby, могут реализовать метод to_path для обеспечения представления этого значения.
В Rails мы используем эту технику для объектов, которые имеют «модельные» характеристики, ожидая, что они будут response_to? (: To_model). Это позволяет нам поддерживать любой объект в соответствующих контекстах, при условии, что эти объекты могут предоставить нам «модельное» представление себя.
Крутые модули
Ruby предоставляет языковую функцию, похожую на "traits" в Scala, Squeak и Perl. По сути, модули Ruby позволяют динамически добавлять новые элементы иерархии классов во время выполнения. Использование super динамически оценивается во время выполнения, чтобы принять во внимание любые модули, которые могли быть добавлены. Это позволяет легко расширять функциональные возможности суперкласса столько раз, сколько необходимо, без необходимости решать, где окажется super во время объявления класса.
Кроме того, модули Ruby предоставляют хуки жизненных циклов append_features и included, которые позволяют использовать модули для изоляции расширений друг от друга и динамического расширения классов на основе включения функций.
Тела классов
В Ruby тела классов не являются особым контекстом. Они просто контекст, в котором self указывает на объект класса. Если вы использовали Rails, вы, вероятно, видели такой код:
class Comment < ActiveRecord::Base
validates_presence_of :post_id
end
Может показаться, что validates_presence_of – это языковая функция, но на самом деле это метод, вызываемый в Comment, предоставляемый ActiveRecord::Base.
Этот метод может выполнять произвольный код (и в контексте класса), включая создание новых методов, выполнение других частей кода или обновление переменной экземпляра класса. В отличие от аннотаций Java, которые должны выполняться во время компиляции, тела классов Ruby могут принимать во внимание информацию времени выполнения программы, такую как динамически предоставляемые параметры или результаты оценки другого кода.
Распространенные ошибки при разработке приложений в Ruby on Rails
Неправильное использование метода предиката
Часто встречающейся ошибкой при разработке Rails является неправильное использование методов предикатов. Для тех, кто не знает, метод предикатов – это любой метод, который синтаксически оканчивается знаком вопроса (?) И должен возвращать только достоверный результат. Достоверный результат может быть true или false, но важно понимать небольшую разницу в некоторых потенциальных значениях. В частности, оба значения false и nil считаются значениями truthy-false в Ruby. Это значит, что они оба будут рассматриваться как ложные или отрицательные результаты при возврате методом предиката. Любое другое значение будет считаться truthy-true, что фактически указывает на истинный или положительный результат.
Слишком частое использование Gems
Самый большой потенциальный недостаток при добавлении нового "джема" (пакет с библиотекой или приложением) в ваше приложение – это ошибки, приводящие к разрушению приложений. В то время как умные разработчики будут использовать только самые стабильные и хорошо проверенные джемы, даже те могут вызывать неожиданное поведение или иметь внутренние ошибки, которые незаметны с самого начала.
Оставляя в стороне возможность того, что сам пакет каким-то образом ошибочен, добавление джема для выполнения какой-либо задачи часто требует больше ресурсов, чем если бы вы сами нашли решение с помощью программирования.
Прямой вызов внешних служб
Еще одна распространенная ошибка при начале работы с Rails – это прямые вызовы приложений сторонним сервисам. Например, когда новый пользователь регистрируется и предоставляет свой номер телефона, ваше приложение может использовать стороннюю службу (например, Twilio) для автоматической отправки пользователю кода подтверждения многофакторной аутентификации.
Если метод #send_authentication_code вызывается напрямую в вашем приложении, то есть вероятность его зависания, в то время как будет выполняться запрос для стороннего сервиса.