belongsToMany in v7 returns an empty array

Viewed 230

My client has an old site built on 4.x that I'm trying to get to work with 7.4. I have most of it working, but am stuck on a belongsToMany relationship

I have a Manufacturer class that has a many-to-many relationship with Subcategories, through a table named membercategory. However, the subcategories property always returns an empty array. What am I missing?

membercategory
+------+------------------+-----------------+
| ID   | FKManufacturerID | FKSubCategoryID |
+------+------------------+-----------------+
| 3203 |               24 |             301 |
| 3202 |               24 |             292 |
| 3201 |               24 |             295 |
+------+------------------+-----------------+

and my Manufacturer class

class Manufacturer extends Model {

  public function subcategories() {

    # have tried swapping the two FK parameters, same result
    return $this->belongsToMany('App\Subcategory','membercategory','FKSubCategoryID','FKManufacturerID');
  }
}

I'm testing it in my controller using this

dd($manufacturers[0]->subcategories);

where $manufacturers[0] returns the object for Manufacturer ID=24

2 Answers

According to the documentation, your code should look like this:

class Manufacturer extends Model {

  public function subcategories() {

    return $this->belongsToMany('App\Subcategory','membercategory','FKManufacturerID','FKSubCategoryID');
  }
}

Looking at the belongsToMany signature:

public function belongsToMany(
    $related, 
    $table = null, 
    $foreignPivotKey = null, 
    $relatedPivotKey = null,
    $parentKey = null, 
    $relatedKey = null, 
    $relation = null) {}

You will see that you need to have the related column in the 4th param and the foreign one in the 3rd.

EDIT

Make sure the types of columns in the model tables and the pivot table match.

Furthermore, according to the belongsToMany signature, you should add the parentKey and relatedKey params if they are not the default: id ( ID != id )

Here is a list of eloquent model conventions in Laravel 7.x and you can see:

Eloquent will also assume that each table has a primary key column named id. You may define a protected $primaryKey property to override this convention:

That means that provided both your model tables have the primary key columns named "ID" ( as you showed you do in the chat ) your code should look like this:

class Manufacturer extends Model {

  public function subcategories() {

    return $this->belongsToMany(
      'App\Subcategory',
      'membercategory',
      'FKManufacturerID',
      'FKSubCategoryID'
      'ID',
      'ID'
    );
  }
}

Just replace the positions of third and fourth columns like this:

return $this->belongsToMany('App\Subcategory', 'membercategory', 'FKManufacturerID', 'FKSubCategoryID');
Related