【问题标题】:Many to Many to Many relation in laravellaravel 中的多对多关系
【发布时间】:2016-06-26 12:36:13
【问题描述】:

这里是我的表迁移(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');
});

如何定义我的 Restaurant、Food、Ingredient 模型及其关系?

这里有一些我需要的例子:

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

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

3-餐厅中所有使用特定食材的菜肴。

...

--------------编辑后-------- ---------

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

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

一个餐厅的所有食物:

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

还有一个获取当前餐厅特定食物的成分

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;
}

【问题讨论】:

    标签: php laravel laravel-5 laravel-5.2


    【解决方案1】:

    基本上是这样的:

    创建两个迁移: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();
    

    用一个变量改变土豆/纽约,你很高兴

    我的代码可能有一些小错别字或错误,但我希望您了解事情的运作方式

    【讨论】:

    • 感谢您的精彩回答,但问题出在这里:两家餐厅的同一道菜有不同的食材(不同餐厅的一道菜的食材可能不同)
    • 一开始你应该提到,我试着编辑
    • 您能否提供一个示例预期结果,以便我可以解决并尝试如何实现它?
    • 例如,纽约的一家餐厅供应带番茄的酿皮披萨,但洛杉矶的另一家餐厅不供应番茄,所以我需要 restaurant_has_foods_with_ingredients 表,正如我在问题中提到的那样,以查找每家餐厅在其填充食品中使用的成分比萨饼。
    • 我有自己的解决方案,我现在编辑并把它放在我的问题中,但我认为它不是一个好解决方案。
    猜你喜欢
    • 2017-05-22
    • 2018-06-15
    • 2018-01-22
    • 2016-02-26
    • 2016-01-04
    • 2018-07-04
    • 1970-01-01
    相关资源
    最近更新 更多