Хотите расти как разработчик и найти крутую работу? Не протирайте штаны — займитесь Open Source проектами. Так легче всего попасть в лучшие команды разработчиков и положить себе в резюме настоящий проект, вместо нелепых «примеров кода». Но найти подходящий проект для участия сложно. Начинаются лень и отговорки, а за ними — отсутствие профессионального роста, критики по-настоящему крутых программистов, уныние и застой.
На Cult of Martians мы собираем интересные задачи для современных веб-программистов. Можно выбрать подходящую по сложности, продолжительности и специализации. Задачи не выдуманы «из воздуха» — каждая решает насущную проблему, и решить ее можно через создание нового Open Source проекта или улучшение существующего. Решайте задачи, прокачивайтесь, присылайте решение на оценку. Лучших могут пригласить к себе на работу компании, программистам которых понравится ваше решен ие.
Для уверенных в себе, задача на неделю
StoreModel — Ruby gem, позволяющий работать с JSON-колонками как с объектами, очень похожими на обычные ActiveRecord
модели.
Необходимо добавить в StoreModel полиморфные типы, которые будут оборачивать значение из JSON в нужный класс–обертку согласно условиям.
Польза: познакомиться с работой атрибутов в Rails, прокачаться в Ruby, принести пользу сообществу.
Пусть в модели Product
есть атрибут config
, у которого есть две версии с разным набором атрибутов. В первой версии были атрибуты model
и color
, во второй — model_name
(вместо model
), color
и version
:
// v1
{
"model": "iPhone X",
"color": "red"
}
// v2
{
"model_name": "iPhone X",
"color": "red",
"version": "2"
}
Необходимо реализовать метод #one_of
в модуле StoreModel
, который будет принимать на вход блок. В качестве аргумента блока будет передаваться JSON из БД, а вернуть необходимо соответствующий класс:
class ConfigV1
include StoreModel::Model
attribute :model, :string
attribute :color, :string
end
class ConfigV2
include StoreModel::Model
attribute :model_name, :string
attribute :color, :string
attribute :version, :integer
end
Config = StoreModel.one_of { |json| json[:version] == 2 ? ConfigV2 : ConfigV1 }
class Product < ApplicationRecord
attribute :config, Config.to_type
end
product = Product.create(config: { model: "iPhone X", color: "red" })
product.config.class # => ConfigV1
product = Product.create(config: { model_name: "iPhone X", color: "red", version: 2 })
product.config.class # => ConfigV2
Бонус: можно предусмотреть сокращенный вариант для случаев, когда в JSON хранится название нужного класса (допустим, в поле type
):
class Product < ApplicationRecord
attribute :config, StoreModel.one_of(class_field: :type).to_type
end
product = Product.create(config: { model: "iPhone X", color: "red", class_field: "ConfigV1" })
product.config.class # => ConfigV1
product = Product.create(config: { model_name: "iPhone X", color: "red", class_field: "ConfigV2" })
product.config.class # => ConfigV2
Обсуждение можно найти в задаче.
#one_of
должен возвращать класс, который реализует методы #to_type
и #to_array_type
(см. модуль TypeBuilders).Инструкции по выполнению