多对多关联下如何处理食谱食材数组的存储(含新增食材)
解决方案
可以通过「查找或创建食材」+「批量关联」的方式实现需求,具体步骤如下:
1. 遍历提交的食材列表,处理已有/新增食材
使用Eloquent的firstOrCreate方法,自动判断食材是否存在:存在则返回已有模型,不存在则创建新模型。同时注意去除食材名称的前后空格,避免因输入冗余空格导致重复创建。
2. 整理关联所需的数据格式
将处理后的食材ID、数量、单位ID整理成Laravel关联所需的数组结构。
3. 批量关联食材到食谱
使用attach方法一次性完成所有食材与食谱的关联,并写入中间表的附加字段。
完整代码示例
在你创建食谱的代码后,添加以下处理逻辑:
// 创建食谱(你的原有代码) $recipe = Auth::user()->recipes()->create([ 'name' => $this->recipe_name, 'description' => $this->recipe_description, 'image' => $recipe_image_path, 'dish_category_id' => $this->recipe_category, 'cuisine_id' => $this->recipe_cuisine, 'menu_id' => $this->recipe_menu, ]); // 处理食材并关联 $ingredientsSyncData = []; foreach ($this->ingredients as $ingredientItem) { // 去除名称前后空格,避免重复创建 $cleanedName = trim($ingredientItem['ingredient_name']); // 查找或创建食材(假设Ingredient模型的名称字段为`name`,如果是其他字段请自行修改) $ingredient = Ingredient::firstOrCreate( ['name' => $cleanedName], // 如果Ingredient有其他必填字段,可在这里添加默认值,例如: // ['category_id' => 1] ); // 整理关联数据:键为食材ID,值为中间表的字段 $ingredientsSyncData[$ingredient->id] = [ 'quantity' => $ingredientItem['ingredient_quantity'], 'unit_id' => $ingredientItem['ingredient_unit'] ]; } // 批量关联食材到食谱 $recipe->ingredients()->attach($ingredientsSyncData);
关键说明
firstOrCreate:第一个参数是查询条件(这里用食材名称),第二个参数是创建新模型时的额外字段(如果有必填字段需要补充)。attach方法:接受一个数组,键是关联模型的ID,值是中间表的附加字段数组,完美匹配你的ingredient_recipe表结构。- 名称去空格:必须处理用户输入的冗余空格,否则会出现"Chicken"和"Chicken "被识别为两个不同食材的问题。
内容的提问来源于stack exchange,提问作者d.shved
相关产品推荐
相关产品推荐

