当图片表需要外键和其他表关联时,表单该如何处理呢?

我的场景是 1:1 和 1:n 的关联模型。下面以 1:n 的情况来讲述一次耗时的尝试经历。

表结构

CREATE TABLE `articles`(
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(50) NOT NULL,
    PRIMARY KEY (`id`)
);

CREATE TABLE `article_pictures`(
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
    `article_id` INT  NOT NULL,
    `path` VARCHAR(500) NOT NULL,
    PRIMARY KEY (`id`)
);

两个模型通过 hasMany 关联。

app\Models\Article.php

class Article extends Model
{
    public function pictures()
    {
        return $this->hasMany(ArticlePicture::class);
    }
}

app\Models\ArticlePicture.php

class ArticlePicture extends Model
{
    public function user()
    {
        return $this->belongsTo(Article::class)
    }
}

仓库代码在此就不赘述了,比较简单。下面是我的尝试经历,都没有达到期望的效果,所以发文提问了。

首先要说的是,这个场景下,文档所提供的在 saving 的时候处理文件的方式其实是不适用的,因为 articile_id 获取不到。

尝试一:

如果直接用 $form->multipleImage('pictures') 的话,在保存的时候,并不能如愿,而是会抛出消息为 Illegal string offset '_remove_'ErrorException 异常。

异常位置:vendor/dcat/laravel-admin/src/Repositories/EloquentRepository.php +781

app\Admin\Controllers\ArticleController.php

class ActivityController extends AdminController
{
    protected function form()
    {
        return Form::make(new Article(['pictures']), function(Form $form) {
            $form->multipleImage('pictures');
        });
    }
}

尝试二:

严格来说这个不算方案,但是想到上面这里其实是只需要更新 pictures.path 的记录,翻看了 关联关系 一节的说明,将上述代码调整为: $form->multipleImage('pictures.path') 结果还是会报错,不过消息变成了 Undefined index: _remove_

异常位置:vendor/dcat/laravel-admin/src/Repositories/EloquentRepository.php +781

尝试三:

class ActivityController extends AdminController
{
    protected function form()
    {
        return Form::make(new Article(['pictures']), function(Form $form) {
            $form->hasMany('pictures', function(Form\NestedForm $form) {
                $form->image('path'); // 可以使用
                // $form->multipleImage('path'); // 会报错 Array to string conversion
            })
        });
    }
}

$form->hasMany() 方法,这个倒是可以上传多张图片了,但是却丢失 multipleImage 那样一次性可以选择多张图片的灵活性,而需要多次点击新增才能上传多张图片,并且,处理不了删除和更新操作了呢😂😂。

疑问:

  1. 这种关联模型场景下,图片上传有更好的方案吗?
  2. 看了下 laravel-admin 中的有关的处理是提供了一个 pathColumn() 方法,正好处理了这个问题,不知作者是否会跟进这种方案啊。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
最佳答案

其他方案可以在saving事件做一下转换或者重写数据仓库的保存方法,数据拿到了,怎么存储这个是可以自己控制的;

pathColumn后面会考虑增加。

3年前 评论
讨论数量: 2

其他方案可以在saving事件做一下转换或者重写数据仓库的保存方法,数据拿到了,怎么存储这个是可以自己控制的;

pathColumn后面会考虑增加。

3年前 评论

好的,我最后是在 saving 阶段按照关联属性的方式格式化了数据进行保存的。

不过文中提到的两个有关于 _remove_ 的报错,看了下源码将 EloquentRepository.php781 行的代码由

if ($related[Form::REMOVE_FLAG_NAME] == 1) {
    $instance->delete();

    continue;
}

调整为

// Undefined index _remove_
if (Arr::get($related, Form::REMOVE_FLAG_NAME) == 1) {
    $instance->delete();

    continue;
}

就可以简单的处理这种报错,不过更多的细节没来及看了。

3年前 评论

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