我正在使用Laravels Eloquent ORM,我遇到了一个特殊关系的小问题。让我们假设我有下表:
Recipe:
id | ... | ingredient1 | ingredient2 | ingredient3 | ingredient4
每个食谱都有4个成分,我从这个特定格式的外部来源获取数据,这就是为什么我将成分作为列而不是正常的多对多关系。
我可以将它们设置为4个一对多关系,但我希望能够写出$ingredient->usedInRecipes()->get()
。
使用4个一对多关系,我必须写$ingredient->usedInRecipesAsIngredient1()->get()
,[...],$ingredient->usedInRecipesAsIngredient4()->get()
并在之后合并它们,这将导致4个查询。
如果您在查询数据库之前知道加入这些内容的好方法,或者如何使4对多关系工作,请回答!
答案 0 :(得分:1)
从问题我无法判断你是否已经尝试过这个问题,尽管我认为你只需要使用一对多关系。
每种成分可能都有一组共同的属性,可以在一个表ingredients
中处理。
id name created_at updated_at
1 Paprika 01/01/1970 00:00:00 01/01/1970 00:00:00
1 Rosemary 01/01/1970 00:00:00 01/01/1970 00:00:00
1 Basil 01/01/1970 00:00:00 01/01/1970 00:00:00
1 Oregano 01/01/1970 00:00:00 01/01/1970 00:00:00
然后是你的recipes
表
id name created_at updated_at
1 Herb Soup 01/01/1970 00:00:00 01/01/1970 00:00:00
要保存关系,数据透视表ingredient_recipe
id recipe_id ingredient_id
1 1 1
2 1 2
3 1 3
4 1 4
现在您所需要的只是belongsToMany
和Recipe
模型上的Ingredient
关系。
如果您愿意,您可以编写保护措施以确保一个食谱只与成分有4种关系,但要保持简单:
Recipe::with('ingredients')->get();
将检索所有成分和食谱。
You can read more about this relationship in the documentation here.
没有Pivots
如果您在ingredient_1
表格中保留了ingredient_2
,recipes
等列,则可以向Recipe
模型添加类似的内容。
public function scopeGetWithIngredients($query)
{
$query->leftJoin('ingredients i1', 'recipes.ingredient_1', '=', 'i1.id')
->leftJoin('ingredients i2', 'recipes.ingredient_2', '=', 'i2.id')
->leftJoin('ingredients i3', 'recipes.ingredient_3', '=', 'i3.id')
->leftJoin('ingredients i4', 'recipes.ingredient_4', '=', 'i4.id')
->select('recipes.name', 'i1.name AS ing_1', 'i2.name AS ing_2');
}
然后您可以使用
获取模型中的成分Recipe::getWithIngredients();
答案 1 :(得分:0)
我找到了一个似乎适用于我所有用例的解决方案。
在配方模型中,我将4种成分定义为一对多关系,并制作了两个辅助范围函数。
class Recipe extends Eloquent {
public function ingredient1()
{ return $this->belongsTo('Ingredient', 'ingredient1'); }
public function ingredient2()
{ return $this->belongsTo('Ingredient', 'ingredient2'); }
public function ingredient3()
{ return $this->belongsTo('Ingredient', 'ingredient3'); }
public function ingredient4()
{ return $this->belongsTo('Ingredient', 'ingredient4'); }
public function scopeHasIngredient( $query, Ingredient $ingredient ) {
return $query-> where( 'ingredient1', '=', $ingredient->id )
->orWhere( 'ingredient2', '=', $ingredient->id )
->orWhere( 'ingredient3', '=', $ingredient->id )
->orWhere( 'ingredient4', '=', $ingredient->id );
}
public function scopeWithIngredients( $query ) {
return $query->with('ingredient1', 'ingredient2',
'ingredient3', 'ingredient4');
}
}
class Ingredient extends Eloquent {
public function ingredientForRecipes() {
return Recipe::hasIngredient( $this )->withIngredients();
}
}
要获取成分的所有食谱,我现在可以致电$ingredient->ingredientForRecipes()->get()
并使用这些成分而无需额外查询。