rails中的高级关联

时间:2010-01-02 10:54:04

标签: ruby-on-rails associations

现在我正在为我的两个模型使用has_and_belongs_to_many关联:

class Books < ActiveRecord::Base
    has_and_belongs_to_many :publishers
end

class Publisher < ActiveRecord::Base
    belongs_to :publishing_company
    has_and_belongs_to_many :books
end

您会注意到每个发布商都属于出版公司:

class PublishingCompany < ActiveRecord::Base
    has_many :publishers
end

我的目标是建立一个允许我这样做的协会:

PublishingCompany.find(1).books

这可能与传统的RoR协会有关吗?

2 个答案:

答案 0 :(得分:5)

您正在寻找的概念是在PublishingCompany类的has_many关联上使用:through参数指定二级关联。做第二学位协会(将加入2个额外的表格)是非常常见的,我不认为我曾经执行过第三学位协会(publishers - &gt; publisher_books - &gt; books),如果我记得正确的Rails获得一旦你推动协会到目前为止,理解你想要做的事情是相当草率的。

第一个值得尝试的选择是:

class PublishingCompany
  has_many :publishers
  has_many :books, :through => :publishers
end

然而Rails documentation声明a:through参数只能用于has_many或belongs_to,这意味着这不应该通过你拥有的has_and_belongs_to_many关联。

你的第二个选择是我在Rails 1上编写的早期系统上必须做的事情。我可能会因此而被投票,但这是我必须做的事情因为我无法处理它。

由于您只是以只读方式使用关联,我只是创建了一个假方法来处理它。请注意,这是最后的手段。作为旁注,我个人不喜欢has_and_belongs_to_many关联,因为我觉得很奇怪,你没有可以操作的对象代表连接表的行。

class Books
  has_many :book_publishers
  has_many :publishers, :through => :book_publishers
end

class BookPublisher
  belongs_to :book
  belongs_to :publisher
end

class Publisher
  has_many :book_publishers  
  has_many :books, :through => :book_publishers
  belongs_to :publishing_company
end

class PublishingCompany
  has_many :publishers
  has_many :book_publishers, :through => :publishers

  def books
    book_publishers.map{|bp|bp.book}
  end
end

# typical use, eager loading to avoid N+1
company = PublishingCompany.first :include => {:book_publishers => :book}
company.books.each {|b| puts b.title}

答案 1 :(得分:0)

这应该适合你。

class PublishingCompany < ActiveRecord::Base
  has_many :books, :through => :publishers, :source => :books
end

:source参数是您需要使用的参数