Лучший способ смоделировать «дружбу» пользователя с различными объектами?
-
13-09-2019 - |
Вопрос
У меня есть следующие сущности:
- Пользователь
- Компания
- Организация
Пользователи должны иметь возможность добавлять пользователей, компании, организации и будущие объекты-тусовки в свой список друзей.
Моя первоначальная идея заключалась в использовании объекта Friendship с полиморфным отношением к другу, например:
Упрощенная схема дружбы:
- ID пользователя
- дружественный_id
- дружественный_тип
User - has_many :businesses, :through => :friendships, :conditions => ['friendable_type=?', 'Business'], :source => :friendable
Моя проблема в том, что Ruby on Rails ActiveRecord не поддерживает has_many через отношения через полиморфные отношения в таблице соединений, например.
В конце концов, я хочу иметь единую таблицу соединений, по которой можно будет перебирать список друзей всех типов, определенных типов и т. д.как показано ниже:
john = User.find(5) john.friendships.map {|friendship| friendship.friendable } john.businesses (has_many :through scoped to only the businesses) john.organizations (has_many :through scoped only to the organizations)
Я рассматривал возможность наследования Пользователя, Бизнеса и Организации от общего класса Party и создания точки ассоциации с базовым классом Party, но в контексте ORM это приводит к куче ненужных полей и кажется грязным.
Мне хотелось бы знать, как другие подошли бы к такой ситуации, когда вы хотите создать отношения «один ко многим» с похожими объектами через общую таблицу соединений с использованием ActiveRecord, избегая при этом этой ошибки::)
Cannot have a has_many :through association 'User#businesses' on the polymorphic object 'Friendship#friendable'.
Любой совет очень ценится.
Спасибо!
Решение 2
Похоже, что плагин Has_many_polymorphs для Rails позволяет мне делать именно то, что я хочу.
http://github.com/fauna/has_many_polymorphs/tree/master
Добавление этой строки в мою модель пользователя дало мне желаемую функциональность:
has_many_polymorphs :friendables, :from => [:businesses, :organizations], :through => :friendships
Другие советы
Не используйте :through, вместо этого используйте :as=>friendable в полиморфных отношениях has_many.