Search code examples
phplaravellaravel-5relationshipbelongs-to

Laravel5.8 belongsTo relation not working for foreach loop


I'm working on Laravel relation using hasMany and belongsTo. It work fine for hasMany relation but I have problem on belongsTo for collection foreach loop. This is my categories table.

    id    name
  --------------
    1     food

And products table.

    id    name         category_id
  ----------------------------------
    1     pizza          1
    2     hamburger      1

Below is hasMany product model.

# Product.php

public function products()
{
    return $this->hasMany(Product::class);
}

Below is belongsTo category model.

# Category.php

public function category()
{
    return $this->belongsTo(Category::class, 'id');
}

I got an error in blade:

Trying to get property of non-object

 <tbody>
   @foreach ($products as $product)
      <tr>
           <td> {{ $product->category->name }} </td>
       </tr>
    @endforeach
  </tbody>

Any advice or guidance on this would be greatly appreciated, Thanks


Solution

  • The problem is the method defintion. The second parameter of the belongsTo method is the foreign key column name. Try this:

    # Product.php
    
    public function category()
    {
        return $this->belongsTo(Category::class, 'category_id');
    }
    

    But, given that your foreign key is the model name followed by _id (category_id), Laravel will look up for this key by default.. so you could simplify it like this:

    # Product.php
    
    public function category()
    {
        return $this->belongsTo(Category::class);
    }
    

    From the documentation:

    ... In the example above, Eloquent will try to match the post_id from the Comment model to an id on the Post model. Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with a _ followed by the name of the primary key column. However, if the foreign key on the Comment model is not post_id, you may pass a custom key name as the second argument to the belongsTo method:

    /**
     * Get the post that owns the comment.
     */
    public function post()
    {
        return $this->belongsTo('App\Post', 'foreign_key');
    }