Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Quiet_Molly's avatar

Double eager loading

I'm trying to display data in ajax from 3 tables which are connected to each other. There are models:

class Product extends Model
{
    protected $table = 'products';

    public function categories()
    {
        return $this->hasMany(ProductCategory::class, 'product_id','id');
    }
}
-------------------------------------------
class ProductCategory extends Model
{
    protected $table = 'product_category';

    public function product()
    {
        return $this->belongsToMany(Product::class);
    }

    public function category()
    {
        return $this->hasOne(Category::class, 'id', 'category_id');
    }
}
-------------------------------------------
class Category extends Model
{
    protected $table= 'categories';

    public function product()
    {
        return $this->hasMany(ProductCategory::class);
    }
}

In Controller my function looks like this:

    public function fetchProducts()
    {
        $products = Product::with('categories')->get();
    return response()->json([
        'products'=> $products,
        ]);
    }

Using this I can get items from ProductCategory table to AJAX:

var eventData = '';
                        $.each(response.products, function(index, item){
                            eventData += '<tr>';
                            eventData += '<td>' + item.id + '</td>';
                            eventData += '<td>' + item.name + '</td>';
                            eventData += '<td>' + item.description + '</td>';
                            if(item.categories.length > 0)
                            {
                                console.log('dupa');
                                eventData += '<td>';
                                eventData += '<select style="width:200px;">';
                                $.each(item.categories, function(key, category){
                                    console.log(category.category_id);
                                    eventData +=    '<option disabled>' + category.name + '</option>'
                                });
                                eventData += '</select>';
                                eventData += '</td>';
                            }
                            eventData += '</tr>';
                        });
                        $("#mainTable").append(eventData);

BUT the problem is that category name is inside of 3rd table: Category, of which 'id' == 'category_id' from ProductCategory. How could I possibly get value from third table?

I tried using

public function fetchProducts()
    {
        $products = Product::with('categories')->with('category')->get();
    return response()->json([
        'products'=> $products,
        ]);

    }

but it throws error: 404. Please wait until the File is Loaded.

I can achieve same thing using php:

foreach ($product->categories as $category) {
				$newProduct = $category->category->name;
        }

but I have to do it in Ajax. What might be solution here?

0 likes
2 replies
edvinaskrucas's avatar
Level 1

Hi,

how about using this:

$products = Product::with(['categories', 'categories.category'])->get();
1 like
bestmomo's avatar

Use @edvinaskrucas solution for eager loading and get infos in Ajax :

var eventData = '';
$.each(response.products, function(index, item){
    eventData += '<tr>';
    eventData += '<td>' + item.id + '</td>';
    eventData += '<td>' + item.name + '</td>';
    eventData += '<td>' + item.description + '</td>';
    if(item.categories.length > 0)
    {
        console.log('dupa');
        eventData += '<td>';
        eventData += '<select style="width:200px;">';
        $.each(item.categories, function(key, category){
            console.log(category.category.name);
            eventData +=    '<option disabled>' + category.category.name + '</option>'
        });
        eventData += '</select>';
        eventData += '</td>';
    }
    eventData += '</tr>';
});
$("#mainTable").append(eventData);
1 like

Please or to participate in this conversation.