Laravel 模型一对多更新问题

product模型建立了一对多的关联关系

    //商品拥有多张缩略图
    public function images()
    {
        return $this->hasMany(ProductImage::class);
    }

新建商品一对多关联插入

 public function store(ProductPost $request)
    {
        try {
            DB::transaction(function () use ($request) {

                //插入数据到商品表
                $product = Product::create($request->all());

                //插入数据到商品描述表
                $product->description()->create([
                    'description' => $request->input('description'),
                    'editor-html-code' => $request->input('editor-html-code')
                ]);

                //插入数据到商品图片表
                $images = [];
                foreach ($request->img as $img) {
                    $images[] = new ProductImage(['image' => $img]);
                }
                $product->images()->saveMany($images);

                //插入数据到商品参数表
                $product->param()->create([
                    'param' => serialize($request->param)
                ]);

            }, 5);

        } catch (\Exception $e) {
            return back()->withInput()->with('danger', $e->getMessage());
        }
        return redirect(route('admin.mall.product.index'))->with('success', '新增商品成功');
    }

//更新商品属性

public function update(ProductPost $request,$id)
    {
        $product=Product::find($id);
        //更改商品表
        $product->update($request->all());

        //更改商品描述表
        $product->description()->update([
            'description' => $request->input('description'),
            'editor-html-code' => $request->input('editor-html-code')
        ]);

        //更改商品图片表
        $product->images()->update([
            //????????
        ]);

        //更改商品参数
        $product->param()->update([
            'param' => serialize($request->param)
        ]);

    }
插入的时候使用了SaveMany的方法插入,那么现在关联更新应该使用什么方法进行更新呢?
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 12

个人感觉,商品关联图片表,在新建商品时会批量插入多张图片,当在编辑时,无法确定图片删除和更换(如:原有5张图片记录删掉了一张成为4条图片记录),建议在编辑时,先一对多关联 Delete,再调用创建时的批量插入~

4年前 评论

@畅畅 感谢回答,我之前的处理方式是 在编辑页面为每个图片设置了删除的点击事件,通过ajax直接从数据库删除,新增加的图片随着post表单执行插入操作. 我主要是想知道laravel有没有比较规范的处理这种更新事件的方法.

4年前 评论

@kangfq 按理来说,像你这种 AJAX 添加,删除的话,后端就不用处理图片了,因为 AJAX 后就已关联的商品,不过我也没有什么好的方法,一般都是先 Delete 关联,然后再全部插入- -。

不过我还是建议类似这种静态的数据,还是序列化放到一个字段中吧,再模型中设置 访问器和修改器。

4年前 评论

@畅畅 删除是用ajax 添加还是用的post 我目前也没找到更好的方法来做这个事情.所以发帖来问一下 谢谢你的建议.

4年前 评论

我一般在做后台数据增删改查时,新增和修改我都写到 store 方法。

    public function store(Request $request)
    {
        $validated = $request->validate([
            'name'         => 'request',
            // other
            'images'       => 'request|array',
            'images.*.url' => 'request',
        ]);
        if ($id = $request->get('id')) {
            $product = Product::findOrFail($id);
        } else {
            $product = new Product();
        }
        $product->name = $validated['name'];
        // other
        $product_image_ids = [];
        foreach ($validated['images'] as $image) {
            if (array_key_exists('id', $image) && $id) {
                $productImage = ProductImage::whereProductId($id)->findOrFail($image['id']);
            } else {
                $productImage = new ProductImage();
                $productImage->product_id = $product->id;
            }
            $productImage->url = $image['url'];
            $productImage->save();
            array_push($product_image_ids, $productImage->id);
        }
        $product->save();
        if ($id) {
            //    删除未关联的ProductImage
            ProductImage::whereProductId($id)->whereNotIn('id', $product_image_ids)->destory();
        }
        //    response
    }
4年前 评论

我通常的做法是会设计一个文件资源表,并有统一的文件上传模块,文件直接上传到OSS,获得文件资源 id,这样的话,编辑产品时的图片修改只需要 sync() 同步一下文件资源 id 即可。

4年前 评论

@xinhuo sync() 应该是多对多的同步吧,我这个是一对多了啊.

4年前 评论
xinhuo 4年前
kangfq (作者) (楼主) 4年前

这个可以参考laravel-admin的一对多关联更新方式,在删除的数据中添加删除标记,处理数据时,有删除标记就直接删除掉,没有的就做更新处理

3年前 评论

来得有点晚了,针对这场景,我是比较数据库图片数组和请求参数图片数组 的差集,标记新增和移除的,再用saveMany和delete处理,不知道这方式行不行

2年前 评论
晏南风 1周前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!