#ruby-on-rails #ruby #design-patterns
#ruby-on-rails #ruby #дизайн-шаблоны
Вопрос:
У меня есть модель собрания с несколькими участниками в разных ролях (скажем, наставник и Ученик). Прямо сейчас у меня есть один участник класса, который имеет атрибут :type с двумя возможными значениями (Tutor / Student). Эти два типа используют одни и те же методы. Каждый из них также имеет свою собственную версию других методов. (скажем, Репетитор, когда назначает встречу, должен получить одобрение директора). Я справляюсь с различиями в методах, перегружая type:
def make_appointment
do stuff
if type = "Tutor"
do something extra
end
end;
Я не определился, идти ли этим путем или иметь два класса, Tutor и Student, которые наследуют класс участника.
Какие проблемы / подводные камни я должен учитывать при принятии решения о том, каким способом это реализовать?
Спасибо.
Ответ №1:
Для методов, которые отличаются незначительно, есть варианты — встроить точки расширения, передавать блоки для улучшения поведения и т. Д.
Почти каждый раз, когда поведение, зависящее от типа, реализуется с помощью сравнения типов, это не очень хорошая идея.
Комментарии:
1. Спасибо, Дэйв. Не могли бы вы привести мне несколько примеров упомянутых вами вариантов? И в чем недостаток сравнения типов?
2. Недостатком является обслуживание и когнитивные издержки, связанные с тем, что часть вашего кода является OO, а часть — нет.
3. Спасибо, Дэйв. Не могли бы вы также указать мне на какую-нибудь ссылку, где я могу узнать о упомянутых вами вариантах?
Ответ №2:
Вы должны использовать какой-нибудь драгоценный камень авторизации, например cancan
, который является наиболее подходящим.
Существует краткое руководство по авторизации на основе ролей. => https://github.com/ryanb/cancan/wiki/Role-Based-Authorization
Абсолютно нормально хранить данные в одной модели. Если существует много разных атрибутов, вы можете использовать полиморфные ассоциации для расширения модели пользователя, но в большинстве случаев это не требуется!
Комментарии:
1. Привет, Дэвид, я использовал cancan для авторизации, но я не уверен, как я могу применить его в этом контексте. Не могли бы вы подробнее рассказать?