laravel中的多对多关系

时间:2016-06-25 14:44:46

标签: php laravel laravel-5 laravel-5.2

这是我的表格迁移(4):

餐馆:

Schema::create('restaurants', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
});

食品:

Schema::create('foods', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
});

成分:

Schema::create('ingredients', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
});

restaurant_has_foods_with_ingredients:

Schema::create('restaurant_has_foods_with_ingredients', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('restaurant_id');
        $table->unsignedInteger('food_id');
        $table->unsignedInteger('ingredient_id');

        $table->foreign('restaurant_id')
            ->references('id')
            ->on('restaurants')
            ->onDelete('cascade');

        $table->foreign('food_id')
            ->references('id')
            ->on('foods')
            ->onDelete('cascade');

        $table->foreign('ingredient_id')
            ->references('id')
            ->on('ingredients')
            ->onDelete('cascade');
});

如何用他们的关系定义我的餐厅,食物,成分模型?

以下是我需要的一些例子:

1 - 所有在其供应菜肴中都含有特定成分的餐馆。

2 - 特定餐厅特定菜肴的所有成分。

3-所有餐厅都含有特定成分的菜肴。

...

------------------------- After Edit -------------------- ---------

我有自己的解决方案,但我认为这不是一个好的解决方案。

现在在我的餐厅模型中,我有两个获取食物的实施

获得餐馆的所有食物:

public function foods()
{
    return $this->belongsToMany('App\Models\Food', 'restaurant_has_foods_with_ingredients')
        ->groupBy('food_id');
}

另一个获得当前restaurunt特定食物的成分

public function foodIngredients(Food $food)
{
    $result = DB::table('restaurant_has_foods_with_ingredients')
        ->select('restaurant_has_foods_with_ingredients.ingredient_id as ingredient_id')
        ->where('restaurant_has_foods_with_ingredients.restaurant_id',$this->id)
        ->where('restaurant_has_foods_with_ingredients.food_id',$food->id)
        ->get();

    $ingredients = array();

    foreach ($result as $row) {
        $ingredients[] = Ingredient::find($row->ingredient_id);
    }
    return $ingredients;
}

1 个答案:

答案 0 :(得分:3)

基本上是这样的:

创建两个迁移:restaurant_foodfood_ingredient

我们有一个

餐厅模型 - 食物模型 - 成分模型

餐馆可以有多种类型的食物,食物也可以供应食物 - >所以我们在这里有很多关系

餐厅模特

class Restaurant extends Model
{
    /**
     * The foods that belong to the Restaurant.
     */
    public function foods()
    {
        return $this->belongsToMany('App\Food');
    }

}

现在好了下一件事

1 - 正如我们之前提到的,可以在许多餐馆提供食物类型,因此我们需要定义反向关系。

2 - 食物中含有许多成分,而且一种成分可用于多种食物中 - >另外多对多

食物模型

class Food extends Model
{
     /**
     * The ingredients that belong to the Food.
     */
    public function restaurants()
    {
        return $this->belongsToMany('App\Restaurant');
    }
    /**
     * The ingredients that belong to the Food.
     */
    public function ingredients()
    {
        return $this->belongsToMany('App\Ingredient');
    }

}

现在

也是如此

成分模型

class Ingredient extends Model
{
    /**
     * The foods that belong to the Ingredient.
     */
    public function foods()
    {
        return $this->belongsToMany('App\Food');
    }

}

好了,现在我们已经完成了所有设置,这就是它的使用方式

添加关系

$Restaurant = Restaurant::find($id);
$Restaurant->foods()->attach($food_id);

从关系中删除

$Restaurant->foods()->detach($food_id);
  

1 - 所有在其供应菜肴中都含有特定成分的餐馆。

$restaurants = App\Restaurant::with(['foods' => function ($query) {
    $query->whereHas(['ingredients' => function ($query) {
      $query->where('name', 'like', 'potato');

}])->get();
  

2 - 特定餐厅特定菜肴的所有成分。

$ingridients = App\Ingredient::whereHas(['foods' => function ($query) {
    $query->where('name', 'like', 'potato')->whereHas(['restaurant' => function ($query) {
      $query->where('name', 'like', 'newyork');

}])->get();
  

3-所有餐厅都含有特定成分的菜肴。

$foods= App\Food::whereHas(['ingredients' => function ($query) {
    $query->where('name', 'like', 'potato');
},
'restaurants' => function ($query) {
        $query->where('name', 'like', 'newyork');
   }
])->get();

用变量改变马铃薯/纽约,你很高兴

我的代码可能会有一些小的错别字或错误,但我希望你知道如何运作