Add in-memory traversal for :through associations

If the :through association is loaded and its :source association
is also loaded, AR can retrieve has_one/has_many :through records
without querying DB.

```ruby
class Author
  has_many :posts
  has_many :comments, :through => :posts
end

class Post
  belongs_to :author
  has_many :comments
end

class Comment
  belongs_to :post
end

author = Author.includes(:posts => :comments).first
# previously `author.comments.to_a` would issue an additional
# redundant SQL query (to load comments again), now instead
# since both `author.posts` and `author.posts.comments` are
# loaded, AR is smart enough to traverse in memory object graph
# to avoid hitting DB. Essentially it will now do
# `author.posts.map(&:comments).compact`.
author.comments.to_a # this will now not issue an SQL query
```

I'm not that comfortable around this part of AR code a thorough review
by AR-association masters is in order :bowtie:. 
This needs to be performant, therefore the code needs to abort on the first failing `association_if_loaded_and_not_stale` while also keeping array allocation at the minimum.