如何使用以下方式设置定向的多对多自联接?

时间:2013-01-17 18:48:55

标签: ruby-on-rails foreign-keys ruby-on-rails-3.2 relationship

我正在为客户设置一个Rails项目,他们希望用户(模型)能够互相跟随(如在Twitter中)。他们还希望能够跟踪一个用户何时开始关注另一个用户。

由于我需要跟踪创建日期,我想,has_many X, :through => Y关系将是要走的路,所以Y会跟踪它的创建日期。

我设置了Follow模型:

class Follow < ActiveRecord::Base
  attr_accessible :actor_id, :observer_id, :follower, :followee
  attr_readonly :actor_id, :observer_id, :follower, :followee

  belongs_to :follower, :class_name => 'User', :foreign_key => :observer_id
  belongs_to :followee, :class_name => 'User', :foreign_key => :actor_id

  validates_presence_of :follower, :followee
  validates_uniqueness_of :actor_id, :scope => :observer_id
end

问题是如何在用户模型中设置关系?

理想情况下,我希望它具有以下内容:

  • :follows将是关联的关注对象,其中self是关注者(observer_id)
  • :followed将是关联的Follow对象,其中self是followee(actor_id)
  • :following将是关联的User对象,其中self是关注者(observer_id)
  • :followers将是关联的User对象,其中self是followee(actor_id)

我不知道如何编写has_many :through部分?我应该使用:source => X还是foreign_key => X?我应该在每个键中放入哪个键(actor_id或observer_id)?

编辑:我目前正在这样做

has_many :follows, :foreign_key => :observer_id
has_many :followed, :class_name => 'Follow', :foreign_key => :actor_id
has_many :following, :class_name => 'User', :through => :follows, :source => :followee, :uniq => true
has_many :followers, :class_name => 'User', :through => :follows, :source => :follower, :uniq => true

并且主要是正在工作。除了:followers之外,所有这些都可以正常工作,但user.followers正在做一些奇怪的事情。 似乎就像检查用户是否关注某人一样,如果是,那么user.followers将返回一个仅包含用户的数组;如果它们不是,则返回一个空数组。

有人有任何建议吗?

1 个答案:

答案 0 :(得分:0)

看起来这是正确的格式:

has_many :follows, :foreign_key => :observer_id
has_many :followed, :class_name => 'Follow', :foreign_key => :actor_id
has_many :following, :class_name => 'User', :through => :follows, :source => :followee, :uniq => true
has_many :followers, :class_name => 'User', :through => :followed, :source => :follower, :uniq => true

对于Rails新手,:uniq => true很重要(正如我在执行此操作时发现的那样),因为它使has_many X, :through => Y关系与返回的重复项保持一致(也就是说,没有它,您可能会获得多个不同的对象,每个使用自己的对象ID,都引用相同的记录/行)。