Size: a a a

Saint P Ruby Community

2021 March 03

m

max in Saint P Ruby Community
Aleksandr Pilishenko
И так неплохо выглядит, не надо менять бойлерплейт на мета-магию в которую не умеет ide, пожалуйста
там всё становится не очень красиво когда появляются callable

module ActivityMonitoring
 module Notifiers
   class Slack
     def self.call(...)
       new(...).call(...)
     end

     def self.notify(...)
       ::SlackNotifier.notify(...)
     end

     def initialize(slack_notifier: self.class.method(:notify), **)
       @notifier = slack_notifier
       super()
     end

     def call(data: {}, **)
       data.each do |group_by, by_group_by|
         text = message(group_by, by_group_by)

         @notifier.call(text: text, channel: '#some_channel') if text.present?
       end
     end
     
     #omited

   end
 end
end
источник

AP

Aleksandr Pilishenko in Saint P Ruby Community
max
там всё становится не очень красиво когда появляются callable

module ActivityMonitoring
 module Notifiers
   class Slack
     def self.call(...)
       new(...).call(...)
     end

     def self.notify(...)
       ::SlackNotifier.notify(...)
     end

     def initialize(slack_notifier: self.class.method(:notify), **)
       @notifier = slack_notifier
       super()
     end

     def call(data: {}, **)
       data.each do |group_by, by_group_by|
         text = message(group_by, by_group_by)

         @notifier.call(text: text, channel: '#some_channel') if text.present?
       end
     end
     
     #omited

   end
 end
end
Нормально, не вижу уродств) Разве что можно вместо извлечения метода в объект лямбду с явным вызовом передавать, чтобы кликабельно было
источник

m

max in Saint P Ruby Community
тут 3rd party API вынесен в DI
что бы в тестах не заморачивать с его моками

у меня RubyMine и так всё правильно по клику на self.class.method(:notify) показывает)
наверное не самый красивый способ это пихать в singleton_class, поэому и сказал что можно воспользоваться контейнерами
но всегда можно создать callable класс/модуль и передавать его def initialize(notifier: SlackNotifier)
источник

AP

Aleksandr Pilishenko in Saint P Ruby Community
Вот контейнеры точно некликабельные :(
источник

AP

Aleksandr Pilishenko in Saint P Ruby Community
Или можно сделать плагин к иде? Может уже кто-то сделал?
источник

AK

Artem Krivonozhko in Saint P Ruby Community
Aleksandr Pilishenko
И так неплохо выглядит, не надо менять бойлерплейт на мета-магию в которую не умеет ide, пожалуйста
источник

m

max in Saint P Ruby Community
это я больше про идиоматичность, типа "с какого черта default implementation лежит в singleton class?", получается что сам singleton_class выступает как контенер зависимостей  с уже подсунутой реализацией. а сам injection осуществляется на уровне конструктора инстанса (что правильно)
источник

m

max in Saint P Ruby Community
конечно, всегда можно создать вложенные модули module Implementation::SlackNotifier с единственным методом self.call и тогда у инстанса будет def initialize(notifier: Implementation::SlackNotifier)
вроде как красиво и SRP соблюдается на всех уровнях
но мы решили что нам и так сойдет =)
типа соглашение - singleton_class хранит дефолтные реализации DI зависимостей для инстанса
источник

w

wi11son in Saint P Ruby Community
источник

w

wi11son in Saint P Ruby Community
вот это можно считать каноничным репо?
источник

NB

Nikita Bulai in Saint P Ruby Community
Я у себя нечто похожее и сделал (о чём где-то выше писал), но были сомнения о том, ок это или не ок. Елинственное, что по итогу я не вызывал один метод репозитория, а несколько (для конечного досутпа к релейшену)
источник

w

wi11son in Saint P Ruby Community
а еще я всегда думал о репозиториях как о штуке, которая исключительно доменная, т.е. UsersRepository нужен, если мы хотим вытащить для дашборда юзеров, а если мы хотим например юзеров с их балансами, которые лежат в другой таблице, то это будет например UsersBalancesRepo, которое строит запрос и возвращает другую структуру, хоть и в базе оно обращается к 100500 таблицам
источник

v

vveare138 in Saint P Ruby Community
не совсем, он возвращает датасет
источник

v

vveare138 in Saint P Ruby Community
wi11son
а еще я всегда думал о репозиториях как о штуке, которая исключительно доменная, т.е. UsersRepository нужен, если мы хотим вытащить для дашборда юзеров, а если мы хотим например юзеров с их балансами, которые лежат в другой таблице, то это будет например UsersBalancesRepo, которое строит запрос и возвращает другую структуру, хоть и в базе оно обращается к 100500 таблицам
ага, верно
источник

w

wi11son in Saint P Ruby Community
т.е. to_a надо в конце метода for_dashboard
источник

v

vveare138 in Saint P Ruby Community
да
источник

AD

Anton Davydov in Saint P Ruby Community
Я бы модель через конструктор прокидывал бы и вместо миксинов наследование бы сделал. А в целом круто, мне нравится 👍
источник

w

wi11son in Saint P Ruby Community
Anton Davydov
Я бы модель через конструктор прокидывал бы и вместо миксинов наследование бы сделал. А в целом круто, мне нравится 👍
я модель через конструктор и прокидываю
источник

w

wi11son in Saint P Ruby Community
а, я понял
источник

w

wi11son in Saint P Ruby Community
ну да, чет я забыл про дефолтное значение
источник