This is a classic example of why :through was added to has_many in 1.1 - see the excellent tutorials at:
http://blog.hasmanythrough.com/articles/2006/02/28/association-goodness http://blog.hasmanythrough.com/articles/2006/03/01/association-goodness-2
Essentially, you add an additional declaration to Library: has_many :books, :through => :shelves
And then you can say
@books = @library.books
and everything should work normally.
Not sure about the next level (library->shelf->book->page) - any hm:t experts want to offer some advice?