Why is eloquent adding underscore to the FK name?

Viewed 271

I have a many-to-many relationship between

extensiontables_registry

and

Ad_groups

The pivot table is extensiontables_registryxad_groups

Now I have this code:

$permittedTables = extensiontables_registry::has("ad_groups")->get();

I want to see what this gets me so I do:

log::info($permittedTables);

And I get this error:

[2020-05-11 07:32:23] local.ERROR: PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'extensiontables_registryxad_groups.extensiontables__registry_id' in 'where clause' in E:\aether-backend\vendor\illuminate\database\Connection.php:331

As far as I can see, laravel/eloquent automatically adds an underscore to my extensiontables_registry_id column on extensiontables_registryxad_groups pivot table. Why does it do that? How can I prevent it?

The three tables currently look like this:

extensiontables_registry:

+----+-----------------------+------------+------------+
| id | extensiontable_name   | created_at | updated_at |
+----+-----------------------+------------+------------+
|  1 | extensiontable_itc    | NULL       | NULL       |
|  2 | extensiontable_sysops | NULL       | NULL       |
|  4 | test                  | NULL       | NULL       |
+----+-----------------------+------------+------------+

extensiontables_registryxad_groups:

+-----------------------------+-------------+------------+------------+
| extensiontables_registry_id | ad_group_id | created_at | updated_at |
+-----------------------------+-------------+------------+------------+
|                           1 |           8 | NULL       | NULL       |
|                           2 |           8 | NULL       | NULL       |
+-----------------------------+-------------+------------+------------+

Ad_groups:

+----+------------------------------------+---------------------+---------------------+
| id | name                               | created_at          | updated_at          |
+----+------------------------------------+---------------------+---------------------+
|  1 | test16                             | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
|  2 | test15                             | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
|  3 | test14                             | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
|  4 | test13                             | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
|  5 | test12                             | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
|  6 | test11                             | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
|  7 | test10                             | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
|  8 | test9                              | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
|  9 | test8                              | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
| 10 | test7                              | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
| 11 | test6                              | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
| 12 | test5                              | 2020-02-26 09:30:21 | 2020-02-26 09:30:21 |
| 13 | test4                              | 2020-03-16 13:27:24 | 2020-03-16 13:27:24 |
| 14 | test3                              | 2020-03-16 13:27:24 | 2020-03-16 13:27:24 |
| 15 | test2                              | 2020-03-16 13:27:24 | 2020-03-16 13:27:24 |
| 16 | test                               | 2020-03-16 13:27:24 | 2020-03-16 13:27:24 |
+----+------------------------------------+---------------------+---------------------+

So there definitely should be SOME result from this query, right? Also, the query itself runs, but when I try to log it, I get the above error.

For the sake of completeness, here are the classes defining the model for eloquent:

AD_Group.php:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Ad_group extends Model
{
  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = [
    'name'
  ];

  /**
   * Hides pivot from return queries.
   *
   * @var array
   */
  protected $hidden = [
    'pivot'
  ];

  /**
   * Many-To-Many relationship with User-Model.
   */
  public function Ad_users()
  {
    return $this->belongsToMany('App\Ad_user', 'Ad_usersxad_groups', 'Ad_group_id', 'Ad_user_id');
  }

  public function extensiontables()
  {
    return $this->belongsToMany('App\extensiontables_registry', 'extensiontables_registryxad_groups');
  }

}

And Extensiontables_registry.php:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Extensiontables_Registry extends Model
{

  /**
 * The table associated with the model.
 *
 * @var string
 */
 protected $table = 'Extensiontables_Registry';

  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = [
    'extensiontable_name'
  ];



  /**
   * Many-To-Many relationship with User-Model.
   */
  public function Ad_groups()
  {
    return $this->belongsToMany('App\Ad_group', 'extensiontables_registryxad_groups');
  }
}
1 Answers

Okay, I found the answer myself: https://laracasts.com/discuss/channels/laravel/custom-name-and-foreign-key-for-manytomany-relationship

TL/DR: Laravel/Eloquent had issues "guessing" the names of my FK attributes on the pivot table. So I had to define them explicitely. See the laravel docs here: https://laravel.com/docs/master/eloquent-relationships#many-to-many

"In addition to customizing the name of the joining table, you may also customize the column names of the keys on the table by passing additional arguments to the belongsToMany method. The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to:

return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');

"

and in my case, on extensiontables_registry.php I needed this:

  public function Ad_groups()
  {
    return $this->belongsToMany('App\Ad_group', 'extensiontables_registryxad_groups', 'extensiontables_registry_id', 'ad_group_id');
  }

And on AD_Group.php I needed this:

  public function extensiontables()
  {
    return $this->belongsToMany('App\extensiontables_registry', 'extensiontables_registryxad_groups', 'ad_group_id', 'extensiontables_registry_id');
  }
Related