Нам нужны твои мозги

Хотите расти как разработчик и найти крутую работу? Не протирайте штаны — займитесь Open Source проектами. Так легче всего попасть в лучшие команды разработчиков и положить себе в резюме настоящий проект, вместо нелепых «примеров кода». Но найти подходящий проект для участия сложно. Начинаются лень и отговорки, а за ними — отсутствие профессионального роста, критики по-настоящему крутых программистов, уныние и застой.

На Cult of Martians мы собираем интересные задачи для современных веб-программистов. Можно выбрать подходящую по сложности, продолжительности и специализации. Задачи не выдуманы «из воздуха» — каждая решает насущную проблему, и решить ее можно через создание нового Open Source проекта или улучшение существующего. Решайте задачи, прокачивайтесь, присылайте решение на оценку. Лучших могут пригласить к себе на работу компании, программистам которых понравится ваше решение.

Бэк: Инструмент для создания частичного, анонимизированного дампа базы данных

Для продвинутых, задача на неделю

Необходимо разработать инструмент (gem) для создания частичного, анонимизированного дампа базы данных Rails (ActiveRecord) приложения.

Это позволит нам использовать на тестовых серверах данные, максимально приближенные к боевым, но при этом не делать полный дамп (который может быть очень большим). Дополнительно в целях безопасности мы также хотим анонимизировать часть данных (персональные данные и т.п.).

Польза: возможность познакомиться с внутренностями ActiveRecord, попрактиковаться в написании Ruby gems и написать инструмент, которым будет активно пользоваться сообщество.

Почему ActiveRecord?

Решение подобной задачи в общем случае (на уровне самой БД) потребует от нас ручного описания связей между данными и постоянной актуализации этих связей.

Наличие же ORM решает эту проблему практически полностью (если все необходимые данные смоделированы с помощью этой ORM).

Как это должно работать?

В первую очередь нам необходимо описать, какие именно данные мы хотим выгрузить и какие изменить. Выглядеть это может так (для структуры приложения, описанной здесь):

EvilSeed.configure do |config|
  # Указываем корневые/начальные объекты – те, которые мы хотим выгрузить, со всеми
  # связанными данными.
  #
  # Первый аргумент – название модели, второй – условия для выборки
  config.root("Forum", id: 42) do |r|
    # мы хотим исключить некоторые ассоциации
    # для этого можем использовать регулярные выражения,
    # по которым будет матчится путь к ассоциации.
    #
    # путь к ассоциации – это строка, составленная из названий ассоциаций, по которым мы пришли,
    # разделенных точкой, где первая часть – это название модели.
    #
    # пример: "forum.users.questions"
    r.exclude(
      [
        # мы не хотим дампить настройки трекинг-пикселей
        /\btracking_pixels\b/
      ]
    )

    # кроме того, мы можем ограничить количество выгружаемых объектов ассоциации;
    # например, не более 100 элементов для всех
    r.limit_associations_size(100)

    # для конкретной ассоциации по пути
    r.limit_associations_size(10, "forum.questions")

    # данный подход удобен, если структура связей ближе к дереву, тогда
    # мы можем отсекать ветки
    # если же в структуре много циклов, то мы должны будем выйти за пределы лимита,
    # чтобы сохранить согласованность
  end

  # системные модели, например, роли
  config.root("Role") do |r|
    # исключаем все ассоциации
    r.exclude(/.*/)
  end

  # Преобразование атрибутов – это глобальная настройка
  config.customize("User") do |u|
    # ставим всем пользователям одинаковый пароль
    u["encrypted_password"] = encrypt("qwerty")
  end

  # Анонимизация – это синтаксический сахар для преобразования,
  # который может использовать, например, Faker для генерации данных
  config.anonymize("User")
    name { Faker::Name.name }
    email { Faker::Internet.email }
  end
end

Запускать будем следующим образом:

EvilSeed.dump("path/to/file")

Советы по реализации

Язык реализации: Ruby.

Инструкции по выполнению

  1. Форкнуть проект evil-seed на GitHub.
  2. Реализовать необходимый функционал.
  3. Сделать Pull Request.