Preserve user supplied JOIN order

JOIN clauses order is important, previous implementation has always put string or arel joins at the end (after auto-generated association joins).

Fixes #12953, #15488, #16635.

/cc @tenderlove
More funky logic to account for multiple return types. Compare with always returning an array.