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:. 
It seems like the failure case for all of these branches involves `loaded_and_not_stale`. I wonder if we can add the appropriate methods to the objects in question, or introduce a new object so the code looks something like:

```ruby
target_assoc = target_assoc_from_through_proxy
if target_assoc.loaded_and_not_stale? # Perhaps having a null object returned from the above if intermediate steps failed
  target_assoc.target # Have the singular vs collection handled by polymorphism (maybe targets is the better method name?)
else
  super
end
```