我有以下模型。用户有UserAction,一个可能的UserAction可以是一个ContactAction(UserAction是一个多态)。有喜欢的LoginAction等其他行动,让Ruby on Rails 3:结合多个has_many或has_many_through关联的结果
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:其具有两个不同的路径Ñ关联。一个是User -> ContactAction.user_id
,另一个是User -> UserAction.user_id -> UserAction.user_actionable_id -> ContactAction.id
。然后将结果(ContactActions)加入到一个列表中,以便使用named_scopes和/或finders进一步处理。
因为我需要这个协会在字面上几十个地方,这将是一个重大的麻烦写(和维护!)自定义SQL的每一个案件。
我宁愿用Rails来解决这个问题,但我也接受其他的建议(如PostgreSQL 8.3版本的程序或东西simliar)。最重要的是,最终,我可以像使用任何其他关联一样使用Rails的便利功能,更重要的是,也可以嵌套它们。
任何想法将是非常赞赏。
谢谢!
为了提供一个排序的答案我自己的问题:
我可能会解决这个使用数据库视图,并根据需要添加相应的关联。针对上述情况,我可以
- 使用SQL在finder_sql创建视图,
- 其命名为“contact_actions_or_requests”
- 修改SELECT子句中添加user_id列,
- 添加应用程序/models/ContactActionsOrRequests.rb,
- ,然后添加 “的has_many:contact_actions_or_requests” 到user.rb.
我不知道如何处理更新记录 - 这似乎不可能与视图 - 但也许这是第一个开始。
目前我应用程序周围散布着find_by_sql调用的混乱。我还没有更新这个使用ARel,尤其是#arel_table方法(请参阅下面的注释)。当我这样做时,我会在这里发布我的结果。 – Jens 2013-01-09 20:24:26
你是如何解决这个问题的? – 2014-11-20 11:02:10
我仍然使用finder_sql和counter_sql,但是将SQL字符串提取到一个类方法中,然后通过proc包含它。这比以前要干净得多,尽管我现在不得不重新考虑我们正在转向Rails 4并且不推荐使用finder_sql。 – Jens 2014-12-18 13:51:56