Стучим по рельсам

03 апреля 2023
Стучим по рельсам

Наш апрельский дайджест мы посвящаем Ruby on Rails. В фокусе патч для пользовательских пространств имён и руководство по развёртыванию RoR на современной OpenBSD. В качестве «изюминки» вспомнили забавный баг GitHub десятилетней давности. Приятного чтения!

Улучшение custom namespaces в Rails 7.1

Что происходит во время автоматической загрузки веб-приложения на Rails? Вначале система сканирует и загружает все поддиректории, находящиеся в директории приложения. Исключение составляют лишь assets, views и javascript. Если мы создадим там любую поддиректорию, то Rails обеспечит её автоматическую загрузку.

При этом стоит помнить, что директории работают в роли пространств имён, а имена файлов должны соответствовать константам, которые они определяют. Если у нас есть файл app/services/users/signup.rb, то внутри него должна быть определена константа Users::Signup. Предположим, что мы хотим, чтобы все сервисы в app/services были в пространстве имён Services.

Получается, надо определить константу Services::Users::Signup. Фактически придётся создать директорию app/services/services. Помещаем туда все наши сервисы и тогда они будут в пространстве имён Services. Не самое элегантное решение. Хотелось бы иметь способ сразу прописать константу вида Services::Users::Signup в файле app/services/users/signup.rb.

С выходом патча #47583 такая возможность появится. Никакой магии, исключительно настройка автозагрузчика:

# config/initializers/autoloading.rb

module Services; end
Rails.autoloaders.main.push_dir("#{Rails.root}/app/services", Services)

В предыдущих версиях (до Rails 7.1) требовалось дополнительно удалять директорию app/services из ActiveSupport::Dependencies.autoload_paths. Теперь же этого делать не придётся. За дополнительной информацией советуем заглянуть в комментарии к PR Improve support for custom namespaces.

Байка про nil

Новое — это хорошо забытое старое. Предлагаем отправиться в 2013 год и вспомнить любопытный баг GitHub. Тогда каждому пользователю без аватарки присваивалась аватарка из профиля разработчика Yehuda Katz. У этого разработчика идентификатор пользователя был равен 4. Ruby же присваивал идентификатору 4 значение nil, то есть отсутствие значения. Таким образом все пользователи без аватарки приравнивались к пользователю с идентификатором 4. Баг пофиксили, но вот для многих так и осталось тайной, почему так произошло.

Разгадка кроется в правильном понимании NIL. В мире Ruby nil представляет собой объект и имеет соответствующий идентификатор (ID). Если два объекта имеют один и тот же ID, значит они оба являются одним и тем же объектом в памяти. Это очень полезно для сравнения объектов, а также позволяет сборщику мусора лучше управлять выделением памяти. Вы можете самостоятельно взглянуть на некоторые зарезервированные ID через интерактивную оболочку irb: 

В мире Ruby nil

В Matz Ruby Interpreter (MRI) значения true/false/nil (а также значения типа Fixnum) обрабатываются особым образом и реально для всех этих объектов в памяти нет структуры с данным. ID, в этом случае, будет указателем на место в памяти, который не будет пересекаться с кучей. За подробностями советуем заглянуть в статью Дхавала Сингха (Dhaval Singh).

Rails и Falcon на OpenBSD

OpenBSD существует уже 28 лет и до сих пор сохраняет статус свободной операционной системы. Концепция OpenBSD подразумевает полное отсутствие несвободных компонентов. Никакой код не может попасть в систему случайным образом, а любая неточность в документации немедленно исправляется. Несмотря на свою «самобытность» этот дистрибутив остаётся хорошим выбором для тех, у кого надёжность и безопасность стоит на первом месте.

OpenBSD

Пару недель назад на Reddit появилась любопытная заметка, что в сервисе GitHub Gists (сервис наподобие Pastebin) выложили подробное руководство по развёртыванию Ruby on Rails + Falcon на OpenBSD. Автор руководства утверждает, что это самое чистое ядро, пользовательское пространство и синтаксис конфигурации. Предложенный им способ позволяет запускать веб-приложения от имени непривилегированного пользователя myappy. Такой пользователь владеет исключительно директориями tmp/ и log/ и не сможет сломать основную систему в случае взлома приложения.

Мы не поленились развернуть инстанс по этому руководству и нашли несколько проблемных моментов. Чтобы не подпортить впечатление, вспомните, что UNIX-системы чувствительны к регистру. Поэтому USER стоит заменить на user.

root# adduser -group user -batch myappy

Проверить, что непривилегированному пользователю назначены верные группы можно командой:

root# id -Gn myappy
myappy user

Точно также вторая команда с созданием привилегированного пользователя dev закончится ошибкой, если не поправить регистр (WHEEL заменить на wheel):

root# adduser -group wheel -batch dev

Когда мы ставим Ruby on Rails, система выдаст предупреждение, которое не стоит игнорировать, а именно создать символьные ссылки. Для версии 3.1.X эти команды выглядят так:

 ln -sf /usr/local/bin/ruby31 /usr/local/bin/ruby
 ln -sf /usr/local/bin/bundle31 /usr/local/bin/bundle
 ln -sf /usr/local/bin/bundler31 /usr/local/bin/bundler
 ln -sf /usr/local/bin/erb31 /usr/local/bin/erb
 ln -sf /usr/local/bin/gem31 /usr/local/bin/gem
 ln -sf /usr/local/bin/irb31 /usr/local/bin/irb
 ln -sf /usr/local/bin/rdoc31 /usr/local/bin/racc
 ln -sf /usr/local/bin/rake31 /usr/local/bin/rake
 ln -sf /usr/local/bin/rdoc31 /usr/local/bin/rbs
 ln -sf /usr/local/bin/rdoc31 /usr/local/bin/rdbg
 ln -sf /usr/local/bin/rdoc31 /usr/local/bin/rdoc
 ln -sf /usr/local/bin/ri31 /usr/local/bin/ri
 ln -sf /usr/local/bin/typeprof31 /usr/local/bin/typeprof

Выделяем всю эту цепочку команд и вставляем в консоль. Без этого последующие команды просто не сработают. Перед тем, как выполнять множество команд, начинающихся на gem git_install, надо не забыть поставить git:

root# pkg_add git

Дальнейшие шаги по клонированию объёмного репозитория и установки гемов могут занять некоторое время, так что наберитесь терпения. Для удобства создания конфигов можно поставить привычный по Linux-системам редактор nano:

root# pkg_add nano

Подытожим: способ рабочий и результатом станет безопасный инстанс на базе OpenBSD. Возможно, кто-то однажды найдёт ваш сервер на OpenBSD с 30-летним аптаймом и приложением, которое будет работать, как ни в чём не бывало.

Интересно посмотреть

Мы рады делиться экспертизой наших специалистов. На YouTube-канале Evrone Academy появилось много новых обучающих видео по Ruby и Rails. Даже если вы давно пишете на Ruby, иногда полезно освежить знания и сверить их с другими экспертами. Ну а для новичков эти видео могут стать отличной отправной точкой.

Короткий и ёмкий формат занятий в 15-20 минут отлично подойдёт даже тем, у кого не слишком много свободного времени. Текстовые версии лекций доступны в нашем блоге на Хабре. Подписывайтесь и отправляйте эти видео своим друзьям, которые хотят начать изучать Ruby. И не забывайте нажать на «колокольчик», чтобы не пропустить новые видео.

Митапы

Онлайн

Ruby meetup №20

19 апреля 2023

Скоро мы встретимся с вами на замечательном Ruby Meetup. Программа мероприятия формируется и скоро станет доступна на странице мероприятия. Кстати, если вы не успели подать доклад, то можете это сделать прямо в режиме онлайн. 

Теперь следить за митапами Evrone стало удобнее. В Telegram-канале Evrone meetups мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи после мероприятий. А ещё, у нас можно выступить, мы поможем оформить вашу экспертизу в яркое выступление. Подписывайтесь и пишите @andrew_aquariuss, чтобы узнать подробности.

Регистрация

Вакансии

Удаленка / Офис

Evrone 

Мы открыты для новых Ruby-разработчиков. В Evrone можно работать удалённо с первого дня, мы поддерживаем и оплачиваем участие в Open-source проектах и выступления на конференциях, а расти в грейдах можно с помощью честной системы проверки навыков и менторства.

Подробнее

Подписаться
на Digest →
Важные новости и мероприятия без спама
Технологии которыми вы владеете и которые вам интересны
Ваш адрес электронной почты в безопасности - вот наша политика конфиденциальности.