Tomas Lucena
Tomas Lucena

Reputation: 1526

avoid ambiguity using laravel scope

I am creating a project in Laravel where each company has plenty of departments... each department has a certain amount of Locations and each Location has assigned devices!

As is possible that different companies use the platform I have created a global scope that basically filter the results by company_id:

class CompanyScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        return $builder->where('company_id', auth()->user()->company_id);
    }
}

All good with this and it filters properly until I am trying to achive the following:

Departments::withCount(['locations','devices'])->get();

At this point I am getting an error that says that the column company_id is ambiguous.. This is happening because table departments , location and devices all have a column company_id and the final query when using the scope does not specify the table name.

Is there any way to add the table name to the scope condition?

Upvotes: 5

Views: 1437

Answers (2)

Matt McDonald
Matt McDonald

Reputation: 5050

Since Laravel 5.5 you can also use this slightly more fluent syntax with the qualifyColumn method.

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Scope a query to only include company users.
     */
    public function scopeCompanyUsers(Builder $builder, User $user): void
    {
        return $builder->where($this->qualifyColumn('company_id'), $user->company_id);
    }
}

Upvotes: 2

Tomas Lucena
Tomas Lucena

Reputation: 1526

Hi in case anyone find the doubt in the future... if you want to specify the table in the Scope you can simply do $model->getTable():

class CompanyScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        return $builder->where($model->getTable().'.company_id', auth()->user()->company_id);
    }
}

Upvotes: 16

Related Questions