0
votes

I have three tables:

  • products table (id, name)
  • ingredients table (id, ingredient_name)
  • products_ingredients table (product_id, ingredient_id)

I have a relation defined in Product

public function ingredients(){
    return $this->hasMany('App\ProductIngredient','product_id','id');
}

When I am listing products using

$products = Product::where('category_id',$cat->id)->with('ingredients')->get();

I am getting this output

"products": [{
    "id": 1,
    "name": "Hesp",
    "category_id": 1,
    "ingredients": [{
        "id": 41,
        "product_id": 1,
        "ingredient_id": 4,
    },
    {
        "id": 42,
        "product_id": 1,
        "ingredient_id": 5,
    }]
}]

Which is right.

What I want is to add the ingredient name in ingredients list like this

"products": [{
    "id": 1,
    "name": "Hesp",
    "category_id": 1,
    "ingredients": [{
        "id": 41,
        "product_id": 1,
        "ingredient_id": 4,
        "ingredient_name": "some name" // I want to add this field
    },
    {
        "id": 42,
        "product_id": 1,
        "ingredient_id": 5,
        "ingredient_name": "some name" // I want to add this field 
    }]
}]

I want to return this as JSON to use in API not in blade where I can call other relations.

How can I achieve this?

1
I don't see that you have the ingredient_name field in your ingredients table. Add it and you should get it returned in the payload. - Mohammed Radwan
Table two: ingredients field: id, ingredient_name - Shaikh Shamim Reza
I have added ingerdient_name. Now what would be the query ? - Shaikh Shamim Reza
Include your Ingredient->Product relation as well - miken32
@miken There relation is already there. How get the output as desired. - Shaikh Shamim Reza

1 Answers

0
votes

You have implemented the many-to-many relationship all wrong. Per the documentation:

Many-to-many relationships are defined by writing a method that returns the result of the belongsToMany method.

...

To define the inverse of a many-to-many relationship, you place another call to belongsToMany on your related model.

class Product extends Model
{
    public function ingredients()
    {
        return $this->belongsToMany('App\Ingredient', 'products_ingredients');
    }
}

class Ingredient extends Model
{
    public function products()
    {
         return $this->belongsToMany('App\Product', 'products_ingredients');
    }
}

Note the related model is first argument to belongsToMany(). It's not needed to create a model for a simple pivot table. Because you have misnamed the pivot table, it must be specified as the second argument to the belongsToMany(). The default name is singular model in alphabetic order, i.e. ingredient_product.


Your output should look something like this now, including the values from the ingredients table, not the pivot table.

"products": [{
    "id": 1,
    "name": "Hesp",
    "category_id": 1,
    "ingredients": [{
        "id": 4,
        "ingredient_name": "some name"
    },
    {
        "id": 5,
        "ingredient_name": "some name"
    }]
}]