diff --git a/src/EloquentDataTable.php b/src/EloquentDataTable.php index edcb9294..bb16943b 100644 --- a/src/EloquentDataTable.php +++ b/src/EloquentDataTable.php @@ -167,7 +167,7 @@ protected function resolveRelationColumn(string $column): string $relation = str_replace('[]', '', implode('.', $parts)); if ($this->isNotEagerLoaded($relation)) { - return $column; + return parent::resolveRelationColumn($column); } return $this->joinEagerLoadedColumn($relation, $columnName); @@ -188,14 +188,14 @@ protected function joinEagerLoadedColumn($relation, $relationColumn) $lastQuery = $this->query; foreach (explode('.', $relation) as $eachRelation) { $model = $lastQuery->getRelation($eachRelation); - $lastAlias = $tableAlias ?: $lastQuery->getModel()->getTable(); + $lastAlias = $tableAlias ?: $this->getTablePrefix($lastQuery); $tableAlias = $tableAlias.'_'.$eachRelation; $pivotAlias = $tableAlias.'_pivot'; switch (true) { case $model instanceof BelongsToMany: $pivot = $model->getTable().' as '.$pivotAlias; $pivotPK = $pivotAlias.'.'.$model->getForeignPivotKeyName(); - $pivotFK = $lastAlias.'.'.$model->getParentKeyName(); + $pivotFK = ltrim($lastAlias.'.'.$model->getParentKeyName(), '.'); $this->performJoin($pivot, $pivotPK, $pivotFK); $related = $model->getRelated(); @@ -211,7 +211,7 @@ protected function joinEagerLoadedColumn($relation, $relationColumn) case $model instanceof HasOneThrough: $pivot = explode('.', $model->getQualifiedParentKeyName())[0].' as '.$pivotAlias; // extract pivot table from key $pivotPK = $pivotAlias.'.'.$model->getFirstKeyName(); - $pivotFK = $lastAlias.'.'.$model->getLocalKeyName(); + $pivotFK = ltrim($lastAlias.'.'.$model->getLocalKeyName(), '.'); $this->performJoin($pivot, $pivotPK, $pivotFK); $related = $model->getRelated(); @@ -227,12 +227,12 @@ protected function joinEagerLoadedColumn($relation, $relationColumn) case $model instanceof HasOneOrMany: $table = $model->getRelated()->getTable().' as '.$tableAlias; $foreign = $tableAlias.'.'.$model->getForeignKeyName(); - $other = $lastAlias.'.'.$model->getLocalKeyName(); + $other = ltrim($lastAlias.'.'.$model->getLocalKeyName(), '.'); break; case $model instanceof BelongsTo: $table = $model->getRelated()->getTable().' as '.$tableAlias; - $foreign = $lastAlias.'.'.$model->getForeignKeyName(); + $foreign = ltrim($lastAlias.'.'.$model->getForeignKeyName(), '.'); $other = $tableAlias.'.'.$model->getOwnerKeyName(); break; diff --git a/src/QueryDataTable.php b/src/QueryDataTable.php index 09d4fa46..f70125b8 100644 --- a/src/QueryDataTable.php +++ b/src/QueryDataTable.php @@ -388,7 +388,7 @@ public function getQuery(): QueryBuilder */ protected function resolveRelationColumn(string $column): string { - return $column; + return $this->addTablePrefix($this->query, $column); } /** @@ -451,7 +451,7 @@ protected function castColumn(string $column): string */ protected function compileQuerySearch($query, string $column, string $keyword, string $boolean = 'or'): void { - $column = $this->addTablePrefix($query, $column); + $column = $this->wrap($this->addTablePrefix($query, $column)); $column = $this->castColumn($column); $sql = $column.' LIKE ?'; @@ -470,20 +470,45 @@ protected function compileQuerySearch($query, string $column, string $keyword, s */ protected function addTablePrefix($query, string $column): string { - if (! str_contains($column, '.')) { - $q = $this->getBaseQueryBuilder($query); - $from = $q->from ?? ''; + // Column is already prefixed + if (str_contains($column, '.')) { + return $column; + } - if (! $from instanceof Expression) { - if (str_contains((string) $from, ' as ')) { - $from = explode(' as ', (string) $from)[1]; - } + $q = $this->getBaseQueryBuilder($query); + + // Column is an alias, no prefix required + foreach ($q->columns ?? [] as $select) { + $sql = trim($select instanceof Expression ? $select->getValue($this->getConnection()->getQueryGrammar()) : $select); + if (str_ends_with($sql, ' as '.$column) || str_ends_with($sql, ' as '.$this->wrap($column))) { + return $column; + } + } + + // Add table prefix to column + return $this->getTablePrefix($query).'.'.$column; + } - $column = $from.'.'.$column; + /** + * Try to get the base table prefix. + * To be used to prevent ambiguous field name. + * + * @param QueryBuilder|EloquentBuilder $query + */ + protected function getTablePrefix($query): ?string + { + $q = $this->getBaseQueryBuilder($query); + $from = $q->from ?? ''; + + if (! $from instanceof Expression) { + if (str_contains((string) $from, ' as ')) { + $from = explode(' as ', (string) $from)[1]; } + + return $from; } - return $this->wrap($column); + return null; } /**