У меня есть простое приложение рельсов с моделями проекта и фазы. Проект имеет много этапов, но только один этап может быть активным (то есть «текущим») одновременно. Я все еще хочу, чтобы другие фазы были доступны, но текущая фаза должна быть основным якорем для приложения. Решение о том, как реализовать это требование, имеет большое значение для того, как я обращаюсь с доступом к модели, проверками и представлениями / формами для обновления создания.
Таким образом, вопрос заключается в следующем: как мне достичь этой ассоциации "has_many, но has-only-one-current", не добавляя слишком много сложности? Основные цели: простота доступа к текущей фазе + обеспечение того, чтобы одновременно не было более 1 активной фазы.
Естественно, у меня были некоторые мысли, и я предложил три варианта, которые я хочу здесь представить. Буду признателен за любые отзывы о том, почему я должен выбрать один вариант, а не другой (или предложение более простого решения):
Первый вариант:
[Project] has_many :phases
[Project] has_one :current_phase, :class_name => "Phase", :conditions => { :current => true }
Недостаток: у меня есть вложенная форма для создания проектов и соответствующих фаз. Кажется, нет простого способа установить точно одну из вновь созданных фаз как активную
Второй вариант:
[Project] has an attribute "current_phase_id"
[Project] has_many :phases
[Project] belongs_to phase, :foreign_key => "current_phase_id"
Недостаток: такой же, как в варианте 1, но у меня есть еще один атрибут и ассоциация own_to, что кажется странным (почему проект должен принадлежать одной из его фаз?)
Третий вариант:
[Phase] has an attribute "active" (boolean)
[Phase] scope :active, :conditions => { :active => true}
# Access to current phase via: project.phases.active
Недостаток: я должен удостовериться, что с помощью проверок существует только одна активная фаза за раз, что сложно, если несколько фаз создаются / редактируются одновременно ИЛИ во время переключения с одной фазы на другую; плюс: project.phases.active возвращает массив, если я не ошибаюсь
Ваша помощь очень ценится. Спасибо!
Обновление
Добавлена награда для поощрения дальнейших мнений по теме. Награда будет присуждена за решение, которое наилучшим образом соответствует основным целям, изложенным выше; или, если альтернативное решение не упомянуто, ответ, который лучше всего объясняет, почему я должен отдать предпочтение одному из приведенных вариантов, а не другому. Спасибо!