The concept you're looking for is specifying a second degree association using the :through parameter on a has_many association on your PublishingCompany class. Doing second degree associations (that will join 2 extra tables) are very common, I don't think I've ever performed a third degree association though (publishers -> publisher_books -> books), and if I recall right Rails gets fairly sloppy at understanding what you're trying to do once you push associations this far.
The first option that's worth trying is:
class PublishingCompany
has_many :publishers
has_many :books, :through => :publishers
end
The Rails documentation however states that a :through parameter can only be used on a has_many or belongs_to, meaning this shouldn't work through the has_and_belongs_to_many association you have.
Your second options is what I had to do on an early system I wrote on Rails 1. I'll likely get voted down for this, but it was something I had to cook up since I couldn't get rails to handle it.
Since you're only going to use the association in a read only fashion, I just created a fake method to handle it. Be warned, this is a last resort. As a side note I personally dislike has_and_belongs_to_many associations as I find it strange that you don't have objects that you can manipulate that represent the rows of the join table.
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}