как избежать полиморфных ассоциаций - PullRequest
12 голосов
/ 16 июня 2010

Учитывая, что вам нужно реализовать новостную ленту, подобную той, которую видели в социальных сетях, например, на Facebook.В настоящее время я использую класс News, который имеет полиморфную ассоциацию, которая может быть любого вида, например, Image, Comment, Friendship, GroupMembership и т. Д. Всякий раз, когда создается объект, также создаются новости.Он отлично работает с AR (ActiveRecords), но у меня возникают проблемы, когда я переключаюсь на DM (DataMapper) или Sequel, так как оба они не поддерживают полиморфные ассоциации и не препятствуют его использованию.

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

Так что мне интересно, как решить проблему без полиморфных ассоциаций, сохраняя при этом хорошую производительность и без других недостатков, таких как возможность добавления метаданных в новости?

Ответы [ 2 ]

22 голосов
/ 18 июня 2010

Отказ от ответственности: я ведущий разработчик Sequel.

Лучший способ сделать это обычно зависит от того, что вы хотите сделать с данными. Один из способов сделать это - иметь столбцы внешнего ключа для всех возможных отношений:

news:
  id
  ... (Other columns)
  image_id
  comment_id
  friendship_id
  group_membership_id

На самом деле нет никакой разницы в производительности при выполнении таких действий по сравнению с общим внешним ключом и хранением имени класса. Для отложенной загрузки вы просто выбираете одно поле внешнего ключа, которое не равно nil / NULL, и выбираете соответствующую ассоциацию для загрузки. Для активной загрузки запросов на таблицу вы просто загружаете все ассоциации одновременно. Это также является более гибким в том смысле, что вы можете легко загружать с помощью JOIN, что невозможно при полиморфном подходе. Кроме того, вы получаете преимущество реальной ссылочной целостности.

Единственным недостатком является то, что если вы хотите добавить больше типов связей в будущем, вам нужно добавить внешние ключи в таблицу.

2 голосов
/ 01 апреля 2013

Вот гем для поддержания ссылочной целостности Полиморфных Ассоциаций на уровне базы данных в Rails:

https://github.com/mkraft/fides

На момент публикации этой статьи есть адаптеры для SQLite3 и Postgresql.

Отказ от ответственности: я написал драгоценный камень.

...