Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel global scopes and joins

I have a global scope setup in Laravel 5.1 which is working fine. However on some of my pages I am using MySQL joins using the Eloquent builder. This results in an ambiguous error:

Column 'cust_id' in where clause is ambiguous

I'm not sure how to avoid this problem. I know that I can use sub queries instead, but is there no other solution?

Here is my scope file:

<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\ScopeInterface;
use App\Customers;
use DB, Session;

class MultiTenantScope implements ScopeInterface
{
    /**
     * Create a new filter instance.
     *
     * @param  UsersRoles $roles
     * @return void
     */
    public function __construct()
    {
        $this->custId = Session::get('cust_id');
    }

    /**
     * Apply scope on the query.
     *
     * @param Builder $builder
     * @param Model $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        if($this->custId) 
        {
            $builder->whereCustId($this->custId); 
        } 
        else 
        {
            $model = $builder->getModel();
            $builder->whereNull($model->getKeyName()); 
        }
    }

    /**
     * Remove scope from the query.
     *
     * @param Builder $builder
     * @param Model $model
     * @return void
     */
    public function remove(Builder $builder, Model $model)
    {
        $query = $builder->getQuery();
        $query->wheres = collect($query->wheres)->reject(function ($where) 
        {
            return ($where['column'] == 'cust_id');
        })->values()->all();
    }  
}
like image 694
V4n1ll4 Avatar asked Aug 06 '15 15:08

V4n1ll4


People also ask

What are global scopes in Laravel?

Laravel global scopes allow us to add constraints to all queries for a given model. You know that Laravel's own soft delete functionality utilizes global scopes to only pull "non-deleted" models from the database.

What is the use of scope in Laravel?

You can use Laravel scopes to DRY up the code. The scope is just a method that you can use in your model to encapsulate the syntax used to execute a query such as above. Scopes are defined by prefixing the name of a method with scope, as below.

What is Laravel join?

The join() method is part of a query builder and is used to carry out the table joining table operation in Laravel.


1 Answers

In order to disambiguate the field, you should add the table name as a prefix:

public function apply(Builder $builder, Model $model)
{
    if($this->custId) 
    {
        $fullColumnName = $model->getTable() . ".cust_id";
        $builder->where($fullColumnName, $this->custId); 
    } 
    else 
    {
        $model = $builder->getModel();
        $builder->whereNull($model->getKeyName()); 
    }
}
like image 82
Ben Claar Avatar answered Oct 06 '22 19:10

Ben Claar