Framework: Pivot table with custom name not working

Created on 14 Aug 2019  路  2Comments  路  Source: laravel/framework

Laravel: 5.8.32
PHP: 7.3.7

Many-to-Many relationship, Company has many Users and vice versa, User can belong to many Companies, the intermediate table is called Access (table: accesses).

Company:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Company extends Model
{
    public function users() {
        return $this->belongsToMany('App\User')
            ->using('App\Access')
            ->withPivot('type', 'permissions')
            ->as('access')
            ->withTimestamps();
    }
}

User:

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    protected $fillable = ['email', 'password', 'first_name', 'last_name'];
    protected $hidden = ['password'];

    public function companies() {
        return $this->belongsToMany('App\Company', 'accesses')
            ->as('access')
            ->withTimestamps();
    }
}

Intemediate Table - Access:

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;

class Access extends Pivot
{
    protected $table = 'accesses';

    protected $casts = [
        'manage_billing'  =>  'boolean'
    ];
}

Steps to reproduce bug:

  1. Make sure the actual table matches the $table as 'accesses'.
  2. Run '$company->users()->get();'.
  3. Gets error 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'xxx.company_user' doesn't exist' <---- Not obeying $table.
  4. Change to "protected $table = 'accesses2'", so that $table table doesn't exist in DB.
  5. Gets error 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'xxx.accesses2' doesn't exist' <---- Obeying $table, but the table doesn't exist (It's called "accesses")
  6. Manually change to "company_user" (Both $table & actual table) and it works

Most helpful comment

You need to specify the custom pivot table as the second argument:

class Company extends Model
{
    public function users() {
        return $this->belongsToMany('App\User', 'accesses')
            ->using('App\Access')           ^^^^^^^^^^
            ->withPivot('type', 'permissions')
            ->as('access')
            ->withTimestamps();
    }
}

You can also provide the pivot class as the second argument and remove using():

class Company extends Model
{
    public function users() {
        return $this->belongsToMany('App\User', 'App\Access')
                                                ^^^^^^^^^^^^
            ->withPivot('type', 'permissions')
            ->as('access')
            ->withTimestamps();
    }
}

All 2 comments

You need to specify the custom pivot table as the second argument:

class Company extends Model
{
    public function users() {
        return $this->belongsToMany('App\User', 'accesses')
            ->using('App\Access')           ^^^^^^^^^^
            ->withPivot('type', 'permissions')
            ->as('access')
            ->withTimestamps();
    }
}

You can also provide the pivot class as the second argument and remove using():

class Company extends Model
{
    public function users() {
        return $this->belongsToMany('App\User', 'App\Access')
                                                ^^^^^^^^^^^^
            ->withPivot('type', 'permissions')
            ->as('access')
            ->withTimestamps();
    }
}

Thanks, your recommendation seems to be working for me. Closing.

Was this page helpful?
0 / 5 - 0 ratings