Наследование отдельных таблиц и где его использовать в Rails - PullRequest
53 голосов
/ 17 февраля 2009

Я застрял в странной проблеме дизайна,

Я работаю над двумя типами профилей. Модели

  • Профиль пользователя (принадлежит пользователю)
  • другие, которые поддерживаются на месте как "боты" (не принадлежат никому)

Типичное поведение ОО этих двух типов профилей одинаково, но распространены только важные атрибуты / свойства (очень важные 5-6), другие свойства, такие как "интересы и т. Д." (Почти 10-15 свойств) нет профилей ботов

Кодер, который работал над этим ранее, создал отдельные модели / контроллеры для профилей ботов / профилей пользователей, которые создают много избыточности везде, а также, как и ожидалось, сложно поддерживать, писать тесты и т. Д. некоторые / все эти проблемы избыточности.

Кто-то предложил в качестве решения наследование одной таблицы

Кто-то предложил использовать вместо этого полиморфные ассоциации.

Какой подход лучше? Когда мы на самом деле используем STI?

Я думал, что STI лучше всего использовать, когда атрибуты одинаковы для моделей и отличаются по поведению.

Мысли о том, что я могу сделать?

Ответы [ 4 ]

35 голосов
/ 17 февраля 2009

Характеристика ИППП как наиболее полезной, когда атрибуты одинаковы, но поведение отличается "примерно правильно", но, возможно, немного ограничивает. Мне нравится использовать STI, когда, как следует из названия, существуют четкие отношения наследования в стиле ОО, а не отношения в стиле базы данных между объектами разных типов.

Если между ботами и пользователями есть общий код, я бы сказал, что STI звучит как победитель. Если есть только некоторые общие атрибуты, это, вероятно, менее применимо, но все же стоит попробовать.

Я довольно экспериментальный человек, поэтому я рекомендую попробовать. Разветвите свой код и реорганизуйте модели в отношения STI. Посмотрите, действительно ли это иссякнет или просто поменяет один набор головных болей на какую-то другую проблему.

Одна вещь, от которой, я думаю, вы не увидите большой пользы, - это сушка ваших контроллеров. По моему опыту, модели STI не часто переводятся в аналогичные контроллеры. Но это было бы что-то еще, чтобы поэкспериментировать. Иногда есть победа, иногда нет.

29 голосов
/ 11 декабря 2009

Я написал статью на эту тему, включая несколько советов по работе с STI:

Наследование в одной таблице в Rails

Короче говоря: должны существовать четкие отношения наследования в стиле OO между объектами (как красноречиво говорится в womble), а не только некоторые общие данные. Если не существует естественной и очевидной иерархии классов, дизайн STI может стать трудным для поддержки по мере развития вашего приложения.

Во-вторых, вы должны подумать, важно ли иметь все данные в одной таблице. С полиморфными ассоциациями ваши запросы к базе данных станут более сложными и, возможно, более медленными. Если вы планируете перечислить все объекты вместе на сайте (например, в таблице), то STI может быть подходящим вариантом.

В-третьих, убедитесь, что ваши дочерние классы не имеют слишком много уникальных атрибутов. Со всеми данными в одной таблице вам не нужно много неглобальных столбцов. Мало того, что они занимают место (не главная проблема), но они делают структуру данных запутанной. Если у вас есть «специальные» столбцы, вы должны явно объяснить их в своем коде.

Наконец, если вы используете STI, я настоятельно рекомендую использовать один контроллер для всех ваших дочерних моделей. Основная функция контроллера заключается в предоставлении доступа к объектам, и если к объектам нужно обращаться совершенно по-разному, STI, возможно, не был правильным выбором дизайна с самого начала.

Ознакомьтесь с моей статьей (ссылка выше), чтобы узнать больше полезных советов.

5 голосов
/ 17 февраля 2009

Я бы, вероятно, использовал либо STI, либо вообще никаких специальных функций. Вы можете назвать все профилем, и вы бы знали, был ли он «ботом», если его пользователь был нулевым. Вы также можете сохранить поле типа без использования STI.

Некоторые вещи могут повлиять на мое решение использовать ИППП:

  • Существует ли логика, специфичная для бота
  • Сколько ботов в сравнении с профилями пользователей (небольшое количество ботов означает, что STI в порядке - много ботов, и я мог бы хранить их где-то еще)

Причина, по которой можно избежать ИППП, заключается в том, что иногда это может помешать вам. Например, это может быть довольно раздражающим, чтобы изменить объект от одного типа к другому (от бота до профиля в данном случае). Иногда лучше использовать простое поле типа.

Стоит отметить, что вам, вероятно, понадобится общий базовый класс, если вы используете STI. Так что вы можете захотеть Profile, BotProfile и UserProfile. Имена за вами. :)

4 голосов
/ 18 февраля 2009

Один признак Rails STI - большинство плагинов (и т. Д.) Не поддерживают его полностью. Вы обнаружите, что исправляете многие из распространенных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...