2

设置

我有一个包含 3 个主要表(用户、链接、主题)和 2 个连接表(link_saves 和 link_topics)的数据模型。我的模型:

用户

has_many :link_saves, :class_name => 'LinkSave', :foreign_key => 'user_id'
has_many :links, :through => :link_saves

链接保存

belongs_to :user
belongs_to :link

关联

has_many :link_saves, :class_name => 'LinkSave', :foreign_key => 'link_id'
has_many :users, :through => :link_saves

has_many :link_topics, :inverse_of => :link
has_many :topics, :through => :link_topics

链接主题

belongs_to :link
belongs_to :topic

话题

has_many :link_topics
has_many :links, :through => :link_topics

问题

我希望能够找到用户为其保存链接的所有主题的列表。我希望能够做到@user.topics并让它跨越从用户到主题的所有 5 个表。更重要的是,我希望它返回一个 ActiveRecord 关系,以便我可以进一步范围/排序/分页用户主题列表,因此这不起作用:

## app/models/user.rb

def topics
  links.collect(&:topics)
end

我走错路了吗?有没有办法通过活动记录来做到这一点,而不必编写所有自定义 SQL?请帮忙!

可能的答案(更新)

使用多个has_many :throughs 来制作所有的跃点。这行得通,但不能成为最佳实践,对吧?

## app/models/user.rb
has_many :link_saves, :class_name => 'LinkSave', :foreign_key => 'user_id'
has_many :links, :through => :link_saves
has_many :link_topics, :through => :links, :uniq => true
has_many :topics, :through => :link_topics, :uniq => true
4

1 回答 1

0

I think this is called a 'nested' has_many through, basically going from A to B to C.

In Rails 3.1 this functionality is now supported http://www.warmroom.com/yesterdays/2011/08/30/rails-3-1-nested-associations/

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html (search for 'Nested')

The example they have is a bit simpler than what you have, but I think it should be enough for you to get some ideas.

class Author < ActiveRecord::Base
  has_many :posts
  has_many :comments, :through => :posts
  has_many :commenters, :through => :comments
end

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :commenter
end

@author = Author.first
@author.commenters # => People who commented on posts written by the author

Prior to Rails 3.1 there was a plugin 'https://github.com/releod/nested_has_many_through'

于 2011-11-30T18:44:31.090 回答