Одиночное наследование таблиц и где их использовать в 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 - большинство плагинов (и т.д.) не поддерживают его полностью. Вы обнаружите, что исправляете многие из распространенных.