Ruby on Rails 3: Объединение результатов из нескольких ассоциаций has_many или has_many_through

У меня есть следующие модели. У пользователей есть 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, как и любые другие ассоциации, и, что более важно, также вкладывать их.

Мы будем очень признательны за любые идеи.

Спасибо!


Чтобы дать своего рода ответ на мой собственный вопрос:

Я, вероятно, решу эту проблему с помощью представления базы данных и добавлю соответствующие ассоциации по мере необходимости. Для вышесказанного я могу

  • использовать SQL в finder_sql для создания представления,
  • назовите его «contact_actions_or_requests»,
  • измените предложение SELECT, чтобы добавить столбец user_id,
  • добавьте приложение / модели / ContactActionsOrRequests.rb,
  • , а затем добавьте has_many: contact_actions_or_requests в user.rb.

Я пока не знаю, как я буду обрабатывать обновления записей - это кажется невозможным с представлением - но, возможно, это это первый старт.

6
задан Jens 7 March 2011 в 19:35
поделиться