Хотите расти как разработчик и найти крутую работу? Не протирайте штаны — займитесь Open Source проектами. Так легче всего попасть в лучшие команды разработчиков и положить себе в резюме настоящий проект, вместо нелепых «примеров кода». Но найти подходящий проект для участия сложно. Начинаются лень и отговорки, а за ними — отсутствие профессионального роста, критики по-настоящему крутых программистов, уныние и застой.
На Cult of Martians мы собираем интересные задачи для современных веб-программистов. Можно выбрать подходящую по сложности, продолжительности и специализации. Задачи не выдуманы «из воздуха» — каждая решает насущную проблему, и решить ее можно через создание нового Open Source проекта или улучшение существующего. Решайте задачи, прокачивайтесь, присылайте решение на оценку. Лучших могут пригласить к себе на работу компании, программистам которых понравится ваше решен ие.
Для продвинутых, задача на неделю
Необходимо реализовать возможность хранить данные для ассоциаций (внешние ключи) в поле колонки типа JSONB (PostgreSQL), сохранив при этом большую часть функционала ассоциаций Active Record.
Польза: возможность научиться работать с внутренностями ActiveRecord и JSONB.
Рассмотрим простой пример:
class Profile < ActiveRecord::Base
# передаём дополнительную опцию `store`,
# которая указывает, что мы хотим хранить ключ
# не в отдельной колонке ("user_id"),
# а в jsonb-колонке "extra".
belongs_to :user, store: :extra
end
class SocialProfile < ActiveRecord::Base
belongs_to :user, store: :extra
end
class User < ActiveRecord::Base
# в обратной связи указываем, что связь через store.
# Вопрос: можно ли опустить явное указание того,
# что используется store, и "узанавать" его из связяннoй модели?
has_one :profile, foreign_store: :extra
has_many :social_profiles, foreign_store: :extra
end
Этот функционал позволяет хранить информацию о разных ассоциациях в одной JSONB колонке.
foreign_key
, inverse_of
и т.д.)preload
/ includes
:User.all.includes(:profile)
#=> SELECT * FROM users
#=> SELECT * FROM profiles where extra->>'user_id'::int IN (...)
eager_load
/ joins
.add_reference :profiles, :users, store: :extra, index: true
Используя JSONB, мы можем реализовать связь многие-ко-многим без промежуточной таблицы (если, например, количество связей небольшое):
class Label < ActiveRecord::Base
# в поле extra['user_ids'] мы будем хранить массив id пользователей,
has_and_belongs_to_many :users, store: :extra
end
class User < ActiveRecord::Base
# здесь список лейблов в extra['label_ids']
has_and_belongs_to_many :labels, store: :extra
end
С точки зрения API функционал должен повторять имеющийся для HABTM.
Также было бы неплохо ответить на вопрос – в каких случаях выгоднее использовать такой подход вместо классического?
Лучшим ответом на этот вопрос будет предъявление бенчмарков и их результатов.