我有以下型号。用户有 UserAction,一个可能的 UserAction 可以是 ContactAction(UserAction 是一种多态)。还有其他操作,例如 LoginAction 等。所以
类用户 < AR::Base has_many :contact_requests, :class_name => "ContactAction" has_many :user_actions has_many_polymorphs :user_actionables, :from => [:contact_actions, ...], :through => :user_actions 结尾 类 UserAction < AR::Base 属于_to:用户 belongs_to :user_actionable, :polymorphic => true 结尾 类 ContactAction < AR::Base 属于_to:用户 命名范围:待定,... 命名范围:活动,... 结尾
这个想法是一个 ContactAction 加入两个用户(在应用程序中具有其他后果)并且总是有一个接收端和一个发送端。同时,一个 ContactAction 可以有不同的状态,例如过期、待处理等。
我可以说@user.contact_actions.pending
或@user.contact_requests.expired
列出用户发送或接收的所有待处理/过期请求。这工作正常。
我现在想要的是一种加入这两种类型的 ContactAction 的方法。即@user.contact_actions_or_requests
。我尝试了以下方法:
类用户 def contact_actions_or_requests self.contact_actions + self.contact_requests 结尾 # 或者 has_many :contact_actions_or_requests, :finder_sql => ..., :counter_sql => ... 结尾
但所有这些都有一个问题,即不可能在关联之上使用额外的查找器或命名范围,例如@user.contact_actions_or_requests.find(...)
或@user.contact_actions_or_requests.expired
。
基本上,我需要一种方法来表达具有两条不同路径的 1:n 关联。一个是User -> ContactAction.user_id
,另一个是User -> UserAction.user_id -> UserAction.user_actionable_id -> ContactAction.id
。然后将结果 (ContactActions) 加入一个列表中,以便使用 named_scopes 和/或查找器进行进一步处理。
由于我在几十个地方都需要这种关联,因此为每种情况编写(和维护!)自定义 SQL 将是一个很大的麻烦。
我更愿意在 Rails 中解决这个问题,但我也愿意接受其他建议(例如 PostgreSQL 8.3 过程或类似的东西)。重要的是,最后,我可以像使用任何其他关联一样使用 Rails 的便利功能,更重要的是,还可以嵌套它们。
任何想法将不胜感激。
谢谢!
为我自己的问题提供某种答案:
我可能会使用数据库视图来解决这个问题,并根据需要添加适当的关联。对于以上,我可以
- 使用 finder_sql 中的 SQL 创建视图,
- 将其命名为“contact_actions_or_requests”,
- 修改 SELECT 子句以添加 user_id 列,
- 添加一个app/models/ContactActionsOrRequests.rb,
- 然后将“has_many :contact_actions_or_requests”添加到 user.rb。
我还不知道我将如何处理更新记录——这似乎是不可能的——但也许这是第一次开始。