没有外键的ActiveRecord关联

时间:2010-10-25 08:39:54

标签: ruby-on-rails activerecord associations

我正在尝试在用户之间建立关系模型。用户可以发起关系,也可以从其他用户接收关系。因此,db中的关系表具有外键“initiator_id”和“recipient_id” 现在,我可以使用以下关联来计算用户发起或接收的关系:

has_many :initiated_relations, :foreign_key => :initiator_id, :class_name => 'Relation', :dependent => :destroy
has_many :received_relations,  :foreign_key => :recipient_id, :class_name => 'Relation', :dependent => :destroy

我想要做的是建立一个关联,它将获取属于用户的所有关系(启动或接收)。尝试以下操作无效,并抱怨缺少“user_id”字段:

has_many :relations, :conditions => 'recipient_id = #{id} or initiator_id = #{id}'

如何创建仅基于条件字段的关联,而不查找默认的foreign_key?或者是否有一种完全不同的解决方法?

2 个答案:

答案 0 :(得分:8)

从你的评论到@ neutrino的回答我明白,你只需要这个“关系”来进行只读操作。如果您使用的是Rails 3,则可以利用它使用延迟提取的事实。 where()方法返回ActiveRecord::Relation对象,稍后您可以修改该对象。所以你可以定义一个这样的方法:

def User < ActiveRecord::Base
  def all_relations
    Relation.where("initiator_id => ? OR recipient_id = ?", id, id)
  end
end

然后你可以这样做:

User.all_relations.where(:confirmed => true).all

答案 1 :(得分:5)

好吧,我可以考虑使用finder_sql

has_many :relations, :finder_sql => 'select * from relations right outer join users
    on relations.recipient_id = #{id} or relations.initiator_id = #{id}'

除此之外,您可以编写一个返回两个关系关联的联合数组的方法,但是您将失去关联接口(phew)的优势。

也许有人会提出更好的解决方案。