Skip to content

Тестовое задание для вакансии Ruby Developer в Realy

Notifications You must be signed in to change notification settings

AlexWayfer/realy_job_test

Repository files navigation

Тестовое задание для вакансии Ruby Developer в Realy

Постановка

Оригинал.

Задача

Написать веб-сервис с использованием фрэймворка Ruby on Rails ~> 6.0 и гема activerecord, который будет возвращать JSON-объект в ответ на запрос к URI /feed методом GET.

Предметная область

Сущность Пользователь с перечисленными ниже признаками:

  • имя
  • возраст
  • местоположение
  • номер телефона
  • настройки (диапазон возрастов от 18 до 100, максимальная дистанция в километрах)
  • время последнего посещения

Формирование данных для выдачи

Помимо хранения информации о экземплярах сущности Пользователь в базе данных необходимо индексировать её в поисковой системе Elasticsearch. Итоговая выдача должна запрашиваться в поисковой системе и отдаваться в ответ на запрос к /feed. Для взаимодействия с поисковой системой использовать гем chewy.

Требования к URI /feed

Необходимо реализовать возможность получать данные постранично, а также указывать кол-во объектов сущности Пользователь на одной странице. Также должна присутствовать возможность получать объекты сущности Пользователь, чьё время последнего посещения не превышает одну неделю.

Требования к тестированию

Для тестирования используйте фрэймворк RSpec, а также вспомогательные гемы на Ваше усмотрение.

Тесты должны покрывать запрос к /feed с разными параметрами, обновление записей в индексе поисковой системы после изменения соответствующих им записей в базе данных.

Нужно использовать фэйковые данные, регистрацию делать не надо.

Решение

При генерации приложения

  • использовал флаг --api;
  • -T, чтобы добавить RSpec отдельно самостоятельно;
  • -d postgresql, хоть про базу и не было ничего указано, но посчитал, что проще и ближе к реальности.

Не понравилось

Rails

  • Puma 4, когда уже есть Puma 5.1.
  • Долгая установка sassc.
    • Но я увидел SASS и в Node, зачем?!
  • Безальтернативно требует (и не устанавливает) yarn.
  • Почему-то убрали информацию о сетапе БД из гайда.
  • generate controller Feed index добавляет роут /feed/index вместо простого /feed.
  • Нет изначально rubocop.
    • При добавлении в шаблоне 70+ offenses.
    • И из генерируемых файлов тоже.
  • rails spec не пропускает аргументы для rspec, вроде --format или --backtrace, зато bundle exec rspec работает как надо.
  • Не нашёл (нормального?) способа сделать json: в render по умолчанию для контролера.
  • Не получилось найти Rails-way для require monkey-patch из lib/.
    • Хотя нашёл config.eager_load = false в config/environments/test.rb, но это всё странно…

Chewy

Elasticsearch

  • Как запустить 2 параллельные инстанции на разных портах (для development и test)?

Узнал новое

  • ALTER USER db_user CREATEDB;.
  • Многое про Elasticsearch (query vs filter, типы данных).
  • Немного про Rails (в основном негативное).
  • Немного про factory_bot. Но до сих пор не уверен, лучше он или fabricator.
  • Паджинация с помощью некоторых существующих решений (см. "Спорное").

Спорное

  • Не вижу смысла выносить "настройки" пользователя в отдельную сущность, так как отношение один-к-одному, и мало возможностей оптимизации, но по постановке задачи (что поля не расписаны отдельно, как остальные, а сгруппированы в "настройки") и для дополнительного опыта (даже если неправильно трактовал постановку) я решил всё же вынести (это же тестовое в вакууме, а не реальное приложение).

  • "местоположение" можно сделать координатами, можно адресом. Выбрал координаты, так как это точнее и именно такой формат приходит от клиентов, насколько я помню, также по ним проще искать, имея "максимальную дистанцию" в настройках. Координаты в PostgreSQL можно хранить по-разному, но так как это тестовое задание, я не хотел привязывать незнакомый мне PostGIS, а выбрал простую встроенную в PostgreSQL декартову геометрию. Однако… позже решил усложнить себе жизнь и привязал PostGIS.

  • Всюду timestamps по умолчанию, включая user_settings.

  • chewy поддерживает kaminari и will_paginate, однако некоторые советуют pagy, и с ним интеграции нет. Оба, к слову, выглядят заброшенными.

    • Выбрал will_paginate, посчитал его потенциально более полезным для себя, и больше понравился по синтаксису, но вряд ли разница большая для данного задания.
    • Однако, у него меньше helper-методов (вроде количества всех страниц), и я решил переключиться на kaminari. Хоть мне и не нужны были эти методы, но это потенциал и гибкость. Также смутил exception у will_paginate при странице 0.
    • Хотя мне и не нравится поведение kaminari, который отдаёт данные первой страницы при запросе страницы < 1. Но в целом поведение более гладкое и предсказуемое.
  • fabricator вроде нравится больше, чем factory_bot, но так как в Realy используется последний — применил его.

  • Советуют в тестах применять Chewy.strategy(:bypass), но, судя по формулировке задачи и упору на тесты, мне необходимо проверять работоспособность именно автоматических хуков.

  • Не получается (нормально) подружить Chewy c ES типом integer_range, не нашёл корня проблемы.

  • Тесты долго выполняются, скорее всего из-за переиндексации Elasticsearch и фабрикации ActiveRecord, но я не разбирался.

  • Не стал делать тестов моделей: там вроде нет логики.

Запуск

Требования

  • Ruby, версия указана в файле .ruby-version
  • PostgreSQL
  • PostGIS
  • Elasticsearch, в приложении включён патч для версии 7

Настройка

Стандартные операции для Rails приложений, которые они почему-то не написали в шаблоне, ну и я не буду.

Тестирование

rails spec, но он не принимает параметров для RSpec, так что я советую bundle exec rspec.

About

Тестовое задание для вакансии Ruby Developer в Realy

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published