private function joinMetaTable(Builder $q, string $key, $type = 'left')
    {
        $relation = $this->meta();
        $metaTable = $relation->getRelated()->getTable();

        // Create an alias for the join, to allow the same
        // table to be joined multiple times for different keys.
        $alias = $metaTable.'__'.$key;

        // If no explicit select columns are specified,
        // avoid column collision by excluding meta table from select.
        if (!$q->getQuery()->columns) {
            $q->select($this->getTable().'.*');
        }

        // Join the meta table to the query
        $q->join("{$metaTable} as {$alias}", function (JoinClause $q) use ($relation, $key, $alias) {
            // Laravel 5.4 changed the method names here
            $foreign_key = method_exists($relation, 'getForeignKeyName') ? $relation->getForeignKeyName() : $relation->getPlainForeignKey();
            $type = method_exists($relation, 'getForeignKeyName') ? $relation->getMorphType() : $relation->getPlainMorphType();

            $q->on($relation->getQualifiedParentKeyName(), '=', $alias.'.'.$foreign_key)
                ->where($alias.'.key', '=', $key)
                ->where($alias.'.'.$type, '=', get_class($this));
        }, null, null, $type);

        // Return the alias so that the calling context can
        // reference the table.
        return $alias;
    }