You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel开发:如何获取当前产品ID实现附件关联存储

问题背景

我目前在产品列表页为每个产品配置了add attachment按钮,点击按钮后会跳转至附件添加表单页。需要从产品表中获取当前产品ID,将附件数据存储到附件表中。


现有代码参考

路由

Route::post('/store/{product}', 'AttachmentController@store')->name('attachment.store');

Product模型

public function attachment()
{
    return $this->hasMany(Attachment::class, 'product_id', 'id');
}

Attachment模型

public function product()
{
    return $this->belongsTo(Product::class, 'product_id');
}

控制器原有代码

public function create()
{        
    return view('document.create', ['prod' => Product::select('id', 'name')->get()]);
}

public function store(Request $request, Product $product) {        
    
    $data['product_id'] = $product->id;

    $data = $request->validate([
        'file' => 'required',
        'file.*' => 'mimes:csv,xlsx,pdf,docx',
    ]);

    $attachmentData = [];   
    if($request->hasFile('file'))
    {
        foreach($request->file('file') as $file) {
            $path = public_path('storage/attachments/'.$request->product_id);
            $fileName = time().'-'.$file->getClientOriginalName();
            $file->move($path, $fileName);
            $attachmentData[] = $fileName;
        }
        $data['file'] = json_encode($attachmentData);
    }
    $attachment = Attachment::create($data);

    return redirect()->route('product.index')->with('success','Attachment added successfully');
}

原有Blade视图

<form method="POST" action="{{route('attachment.store')}}" enctype="multipart/form-data">
    @csrf
    <h3><b>Add Attachment</b></h3>
    <input type="submit" class="btn btn-primary mr-2" value="Save">

    <div class="row">
        <h4 class="card-title">General</h4>

        <input type="text" name="product_id" value="{{ $product->id ?? '' }}" hidden>

        <div class="form-group">
            <label for="name">Name</label>
            <input type="text" id="name" class="form-control" name="name" required>
        </div>
        <div class="form-group">
            <label>Attachment </label>
            <div class="input-group-append">
                <label for="attachment" class="btn btn-info">Upload</label>
                <input id="attachment" type="file" name="file[]" multiple required>
            </div>
        </div> 
    </div>
</form>

解决方案

1. 新增附件创建页路由

补充带产品ID参数的create路由,用来接收从列表页传过来的当前产品ID

Route::get('/create/{product}', 'AttachmentController@create')->name('attachment.create');

2. 修改产品列表页的跳转按钮

遍历产品列表时,给每个add attachment按钮绑定当前产品ID作为跳转参数

<a href="{{ route('attachment.create', $product->id) }}" class="btn btn-success">add attachment</a>

3. 修改控制器create方法

接收路由传过来的产品实例,直接传到视图即可,不需要查询所有产品

public function create(Product $product)
{        
    return view('document.create', compact('product'));
}

4. 修改Blade表单提交地址

给路由补充产品ID参数,表单提交时会自动把产品ID带到请求中

<form method="POST" action="{{route('attachment.store', $product->id)}}" enctype="multipart/form-data">
    @csrf
    <h3><b>Add Attachment</b></h3>
    <input type="submit" class="btn btn-primary mr-2" value="Save">

    <div class="row">
        <h4 class="card-title">General</h4>
        <!-- 隐藏域可保留也可删除,路由参数已经携带了产品ID -->
        <input type="text" name="product_id" value="{{ $product->id }}" hidden>

        <div class="form-group">
            <label for="name">Name</label>
            <input type="text" id="name" class="form-control" name="name" required>
        </div>
        <div class="form-group">
            <label>Attachment </label>
            <div class="input-group-append">
                <label for="attachment" class="btn btn-info">Upload</label>
                <input id="attachment" type="file" name="file[]" multiple required>
            </div>
        </div> 
    </div>
</form>

5. 修复store方法逻辑bug

原有代码先给$data赋值产品ID后又被验证结果覆盖,会导致产品ID丢失,调整逻辑顺序即可

public function store(Request $request, Product $product) {        
    // 先做参数验证,补充name字段的验证规则
    $validated = $request->validate([
        'name' => 'required|string|max:255',
        'file' => 'required',
        'file.*' => 'mimes:csv,xlsx,pdf,docx',
    ]);

    $attachmentData = [];   
    if($request->hasFile('file'))
    {
        // 自动创建存储目录,避免目录不存在报错
        $path = public_path('storage/attachments/'.$product->id);
        if (!file_exists($path)) {
            mkdir($path, 0777, true);
        }
        foreach($request->file('file') as $file) {
            $fileName = time().'-'.$file->getClientOriginalName();
            $file->move($path, $fileName);
            $attachmentData[] = $fileName;
        }
        $validated['file'] = json_encode($attachmentData);
    }
    // 把产品ID加入待存储数据
    $validated['product_id'] = $product->id;
    $attachment = Attachment::create($validated);

    return redirect()->route('product.index')->with('success','Attachment added successfully');
}

内容的提问来源于stack exchange,提问作者xyz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 15:09:03