require the files we need so the classes are stand-alone
parent is always passed in, so make it non-optional
simplify the JoinAssociation constructor, check validity *before*
Set the join type on construction

We always set the join type immediately after construction, just make it
part of the constructor and we can skip that step
Always pass parameters to `build`

We always know the parameters in advance, so we don't need to build it
in to the method signature
hashes are ordered, so we do not need to sort
inject down the hash cache