У меня есть простое приложение для рельсов с моделями проекта и фазы. Проект имеет много фаз, но только по фазе может быть активным (т.е. "Ток" ) за раз. Я все еще хочу, чтобы другие фазы были доступны, но текущая фаза должна быть основным якорем для приложения. Решение о том, как реализовать это требование, имеет серьезные последствия для того, как я обрабатываю доступ к модели, проверки и представления/формы для создания обновления.
Итак, возникает вопрос: как мне достичь этой "has_many, но имеет единственно-единственную связь", не добавляя слишком много сложностей? Основными задачами являются: простота доступа к текущей фазе + обеспечение не более чем одной активной фазы за раз.
Естественно, у меня были некоторые мысли, и я придумал три варианта, которые я хочу здесь представить. Любые отзывы о том, почему я должен выбрать один вариант по сравнению с другим (или предложение более простого решения), будут оценены:
Первый вариант:
[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, но у меня есть другой атрибут и ассоциация belongs_to, которая кажется странной (почему проект должен принадлежать одной из его фаз?)
Третий вариант:
[Phase] has an attribute "active" (boolean)
[Phase] scope :active, :conditions => { :active => true}
# Access to current phase via: project.phases.active
Недостаток: я должен обеспечить с помощью валидации, что за один раз активна только одна активная фаза, что сложно, если одновременно создавать или редактировать несколько фаз или во время переключения с одной фазы на другую; plus: project.phases.active возвращает массив, если я не ошибаюсь
Ваша помощь очень признательна. Спасибо!
Update
Добавлена щедрость, чтобы поощрять дальнейшие мнения по этой теме. Bounty будет награжден решением, которое наилучшим образом отразит основные цели, изложенные выше; или если альтернативное решение не упоминается, ответ, который лучше всего объясняет, почему я должен одобрять один из указанных вариантов над другим. Спасибо!