Ruby: работа в контексте некоторого пространства имен

#ruby #namespaces

#ruby #пространства имен

Вопрос:

Вот фрагмент кода, который использует enum много раз:

 .where("items.state in (#{Workflow::ItemStatus::MOVING},#{Workflow::ItemStatus::WAITING},#{Workflow::ItemStatus::EXECUTING},#{Workflow::ItemStatus::ASSIGNED})")
  

Что мне не нравится, так это Workflow::ItemStatus многократно повторяющееся пространство имен, которое выдает длинную строку.

Я хотел бы обернуть код в некоторую конструкцию, которая позволит мне делать:

 .where("items.state in (#{[MOVING, WAITING, EXECUTING, ASSIGNED].join(',')})")
  

Комментарии:

1. Если Workflow::ItemStatus это модуль, включите его.

2. @Michael Kohl: К сожалению, есть два пространства имен с синхронизированными перечислениями: Proto::ItemStatus и Workflow::ItemStatus (но это не одно и то же). Если я включу оба модуля, имена будут неоднозначными. Но в любом случае спасибо.

Ответ №1:

Вы можете написать

 constants = %i(MOVING WAITING EXECUTING ASSIGNED)
.where("items.state in (?)", constants.map { |c| Workflow::ItemStatus.const_get(c) })
  

Ответ №2:

Я разработал для себя компромиссное решение:

 st = Workflow::ItemStatus
Item.joins(.....).where("items.state in (#{st::MOVING},#{st::WAITING},#{st::EXECUTING},#{st::ASSIGNED})")