У меня есть следующие модели. У пользователей есть UserActions, и одним из возможных UserAction может быть ContactAction (UserAction - это полиморфизм). Существуют и другие действия, такие как LoginAction и т. Д. Итак
class User < AR::Base has_many :contact_requests, :class_name => "ContactAction" has_many :user_actions has_many_polymorphs :user_actionables, :from => [:contact_actions, ...], :through => :user_actions end class UserAction < AR::Base belongs_to :user belongs_to :user_actionable, :polymorphic => true end class ContactAction < AR::Base belongs_to :user named_scope :pending, ... named_scope :active, ... end
Идея состоит в том, что ContactAction объединяет двух пользователей (с другими последствиями в приложении) и всегда имеет принимающую и отправляющую стороны. В то же время ContactAction может иметь разные состояния, например, истекший, ожидающий и т. Д.
Я могу сказать @ user.contact_actions.pending
или @ user.contact_requests.expired
чтобы перечислить все ожидающие / просроченные запросы, отправленные или полученные пользователем. Это работает нормально.
Теперь мне нужен способ присоединить к обоим типам ContactAction. Т.е. @ user.contact_actions_or_requests
. Я пробовал следующее:
class User def contact_actions_or_requests self.contact_actions + self.contact_requests end # or has_many :contact_actions_or_requests, :finder_sql => ..., :counter_sql => ... end
, но все они имеют проблему, заключающуюся в невозможности использования дополнительных средств поиска или named_scopes поверх ассоциации, например @ user.contact_actions_or_requests.find (...)
или @ user.contact_actions_or_requests.expired
.
По сути, мне нужен способ выразить связь 1: n, имеющую два разных пути. Один из них - Пользователь -> ContactAction. user_id
, другой - User -> UserAction.user_id -> UserAction.user_actionable_id -> ContactAction.id
. А затем объедините результаты (ContactActions) в один список для дальнейшей обработки с помощью named_scopes и / или средств поиска.
Поскольку мне нужна эта ассоциация буквально в десятках мест, было бы очень сложно написать (и поддерживать!) Пользовательский SQL на всякий случай.
Я бы предпочел решить эту проблему в Rails, но я также открыт для других предложений (например, процедура PostgreSQL 8.3 или что-то подобное). Важно то, что в конечном итоге я могу использовать удобные функции Rails, как и любые другие ассоциации, и, что более важно, также вкладывать их.
Мы будем очень признательны за любые идеи.
Спасибо!
Чтобы дать своего рода ответ на мой собственный вопрос:
Я, вероятно, решу эту проблему с помощью представления базы данных и добавлю соответствующие ассоциации по мере необходимости. Для вышесказанного я могу
Я пока не знаю, как я буду обрабатывать обновления записей - это кажется невозможным с представлением - но, возможно, это это первый старт.