Ruby on rails 没有外键的ActiveRecord关联

Ruby on rails 没有外键的ActiveRecord关联,ruby-on-rails,activerecord,associations,Ruby On Rails,Activerecord,Associations,我试图在用户之间建立一个关系模型。用户可以启动关系,也可以从另一个用户接收关系。因此,数据库中的关系表具有外键“启动器id”和“收件人id”。 现在,我可以通过以下关联计算出用户发起或接收的关系: has_many :initiated_relations, :foreign_key => :initiator_id, :class_name => 'Relation', :dependent => :destroy has_many :received_relations,

我试图在用户之间建立一个关系模型。用户可以启动关系,也可以从另一个用户接收关系。因此,数据库中的关系表具有外键“启动器id”和“收件人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”字段:


如何创建仅基于条件字段的关联,而不查找默认的外键?或者有没有完全不同的方法来解决这个问题?

好吧,我可以考虑使用
finder\u sql
来解决这个问题:

has_many :relations, :finder_sql => 'select * from relations right outer join users
    on relations.recipient_id = #{id} or relations.initiator_id = #{id}'
除此之外,您只需编写一个方法,返回两个关系关联的联合数组’,但您将失去关联接口(phew)的优势


也许有人会想出一个更好的解决方案。

从您对@neutrino的回答的评论中,我理解,您只需要在只读操作中使用这个“关系”。如果您使用的是Rails3,那么您可以利用它使用惰性抓取这一事实。
where()
方法返回
ActiveRecord::Relation
对象,您可以稍后修改该对象。因此,您可以定义如下方法:

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

我已经尝试过使用finder_sql,但是如果有其他方法来实现这一点,我更愿意这样做,因为使用finder_sql我会失去所有关联功能。e、 g:我不能执行
user.relations.find(:all,:conditions=>{:confirm=>true})
或任何其他类似的函数。谢谢你的意见,非常感谢。我认为这不管用#{id}是在类级别计算的,而不是在实例级别。它需要是一个proc,从rails v3.2.13开始,它只在:conditions选项上受支持。Rails 4在这方面会更好。
:finder\u sql
已被弃用,并已从Rails 4.1中删除。所以这个解决方案不起作用了。这似乎是一个非常优雅的解决方案,是的,我只希望这个关系用于只读目的。但是,我没有使用Rails 3,所以这对我来说不起作用:(.1表示很好的答案:)。作用域很好,但您不能急于加载它们
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