Одиночное наследование таблиц и где их использовать в Rails
Я застрял в странной проблеме с дизайном,
Я работаю над двумя типами профилей. Модели,
- Профиль пользователя (принадлежит Пользователю)
- другие, которые поддерживаются на месте как "боты" (не принадлежат никому).
Типичное поведение OO этих двух типов профилей одинаково, но только важные атрибуты/свойства являются общими (очень важные из них 5-6), другие свойства, такие как "интересы и т.д." (почти 10-15 свойств) не существует для профилей ботов
Кодер, который работал над этим ранее, создал отдельные модели/Контроллеры для профилей ботов/профилей пользователей, которые создают много избыточности повсюду, а также, как и ожидалось, трудно поддерживать, писать тесты и т.д. Я хотел СУШИТЬ это, по крайней мере, решить некоторые/все эти проблемы избыточности.
Кто-то предложил одностраничное наследование как решение
Кто-то предложил использовать полиморфные ассоциации.
Какой лучший подход. Когда мы действительно используем STI?
Моя собственная мысль была STI лучше всего использовать, когда атрибуты одинаковы для моделей, и они отличаются поведением.
Мысли о том, что я могу сделать?
Ответы
Ответ 1
Характеризуя ИППП, как правило, полезно, когда атрибуты одинаковы, но различия в поведении "правы", но, возможно, немного ограничены. Мне нравится использовать STI, когда есть, как следует из названия, четкое отношение наследования стиля OO, а не отношение типа базы данных между объектами разных типов.
Если между ботами и пользователями существует общий код, я бы сказал, что STI звучит как победитель. Если есть только некоторые общие атрибуты, это, вероятно, менее применимо, но все же стоит пойти на.
Я довольно опытный человек, поэтому моя рекомендация - дать ему уйти. Отделите свой код и переформулируйте модели в отношение STI. Посмотрите, действительно ли это иссушает, или просто сводит один набор головных болей к какой-то другой проблеме.
Одна вещь, я думаю, что вы не увидите большой выгоды от высыхания ваших контроллеров. По моему опыту, модели STI нередко переходят в аналогичные контроллеры. Но это было бы чем-то еще, с чем можно было бы экспериментировать. Иногда бывает победа, иногда нет.
Ответ 2
Я написал статью по этой теме, включая несколько советов по работе с STI:
Наследование отдельных таблиц в Rails
Вкратце: должно быть четкое отношение наследования типа OO между объектами (как это красноречиво заявлено womble), а не только некоторые общие данные. Если нет естественной и очевидной иерархии классов, дизайн STI может стать трудноподдерживающим по мере развития вашего приложения.
Во-вторых, вы должны подумать, важно ли иметь все данные в одной таблице. С полиморфными ассоциациями ваши запросы к базе данных будут более сложными и, вероятно, медленнее. Если вы планируете перечислять все объекты вместе на сайте (например, в таблице), то STI может быть способом.
В-третьих, убедитесь, что у ваших дочерних классов не слишком много уникальных атрибутов. Со всеми данными в одной таблице вам не нужно много неглобальных столбцов. Они занимают не только место (не большое беспокойство), но они создают путаницу в структуре данных. Если у вас есть "специальные" столбцы, вы должны явно объяснить их в своем коде.
Наконец, если вы используете STI, я настоятельно рекомендую использовать один контроллер для всех ваших дочерних моделей. Основная функция контроллера - обеспечить доступ к объектам, и если к объектам необходимо получить доступ по-разному, то STI, возможно, не был правильным выбором дизайна для начала.
Ознакомьтесь с моей статьей (ссылка выше) для получения более полезных советов.
Ответ 3
Я бы, вероятно, использовал либо STI, либо никаких специальных функций вообще. Возможно, вы сможете назвать все профилем, и вы знаете, был ли он "бот", если его пользователь был нулевым. Вы также можете сохранить поле типа, не используя STI.
Некоторые вещи повлияют на мое решение использовать STI:
- Существует ли бот-специфическая логика
- Сколько ботов существует в сравнении с профилями пользователей (небольшое количество ботов означает, что STI в порядке - много ботов, и я мог бы их хранить где-то в другом месте).
Причина, по которой можно избежать ИППП, иногда может мешать вам. Например, может быть довольно неприятно изменять объект из одного типа в другой (в этом случае Bot для профиля). Иногда бывает простое поле типа.
Стоит отметить, что вам, вероятно, понадобится общий базовый класс, если вы используете STI. Поэтому вы можете захотеть Profile
, BotProfile
и UserProfile
. Имена до вас.:)
Ответ 4
Один из них Rails STI - большинство плагинов (и т.д.) не поддерживают его полностью. Вы обнаружите, что исправляете многие из распространенных.