rails中的高级关联

blo*_*ilk 2 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
Run Code Online (Sandbox Code Playgroud)

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

class PublishingCompany < ActiveRecord::Base
    has_many :publishers
end
Run Code Online (Sandbox Code Playgroud)

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

PublishingCompany.find(1).books
Run Code Online (Sandbox Code Playgroud)

传统的RoR协会有可能吗?

Mic*_*ael 5

您正在寻找的概念是在PublishingCompany类的has_many关联上使用:through参数指定二级关联.做第二学位协会(将加入2个额外的表)是非常常见的,我不认为我曾经执行过第三学位协会(publishers - > publisher_books - > books),如果我记得正确的Rails变得相当草率一旦你推动协会这一点,你就能理解你想要做什么.

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

class PublishingCompany
  has_many :publishers
  has_many :books, :through => :publishers
end
Run Code Online (Sandbox Code Playgroud)

Rails文档然而指出一个:通过参数只能在的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}
Run Code Online (Sandbox Code Playgroud)