#ruby-on-rails #namespaces #model #sti
#ruby-on-rails #пространства имен #Модель #sti
Вопрос:
Мне нужно иметь возможность планировать напоминания для пользователей. Итак, я подумал, что мог бы просто создать базовую модель Reminder
и использовать STI для создания классов-потомков, которые переопределяют функцию fire()
, вызываемую при срабатывании напоминания. Но разные роли пользователей имеют похожие типы напоминаний. Таким образом, они должны иметь пространство имен, например, Adult::BrushTeethReminder
отправляет электронное письмо пользователю, Kid::BrushTeethReminder
публикует на стене FB ребенка.
Возможно ли это с помощью STI и если да, то как? Другой способ, который я вижу, — это просто добавить префикс к именам моделей, таким как KidBrushTeethReminder
. Или идите еще глубже — напишите фабричный метод, который создает объекты в соответствии с типом. Или есть более чистый способ?
Ответ №1:
Я вижу два типа напоминаний, одно для взрослых и одно для детей. Лично я бы использовал STI с именем Reminder и имел бы одну модель под названием BrushTeeth, наследуемую от Reminder. В модели BrushTeeth у меня было бы два логических столбца с именами for_adult и for_kid .
В вашем пространстве имен для Adult вы можете проверить BrushTeeth, запросив, установлено ли для столбца for_adult значение TRUE, и основывать свою логику / реализацию на этом. А для пространства имен Kid необходимо проверить столбец for_kid.
Наличие напоминания в качестве основы дает вам возможность легко создавать другие напоминания (например, о душе, ванне, гвоздях и т.д.). Модель напоминания также поставляется со столбцом типа, поскольку это модель STI.
Надеюсь, это поможет.
Комментарии:
1. На самом деле я намеревался использовать
Reminder
в качестве базового класса. Но Kid и Adult — это всего лишь простой пример, на самом деле существует множество разных ролей и напоминаний, поэтому добавление столбцовfor_kid
,for_adult
не будет элегантным способом.
Ответ №2:
Я обнаружил, что вы можете использовать STI для моделей в разных пространствах имен. Вам просто нужно поместить их в соответствующие вложенные папки. Например, Kid::BrushTeethReminder
должно быть помещено под app/models/kid
в файл brush_teeth_reminder.rb