2016-06-25 28 views
2

这里我表迁移(4):多对多在laravel许多关系

餐馆:

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 - 所有菜肴在餐厅的特定成分。

...

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

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

现在在我的餐厅模式,我有两种实现获取食物

一拿到餐厅所有的食物:

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

回答

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(); 

变化土豆/纽约,你是好去

我的代码可能有一些细微的拼写错误或错误,但我希望你得到的想法是如何工作

+0

谢谢您的出色答案,但问题在这里: 两家餐厅的同一道菜有不同的配料(不同餐厅的料理可能不同) –

+1

你应该提到,起初,生病尝试和编辑 –

+1

你能否提供我一个预期的例子结果,所以我可以解决并尝试如何实现它? –