【问题标题】:How can I delete a single image from a post with multiple images in Laravel 7如何从 Laravel 7 中包含多个图像的帖子中删除单个图像
【发布时间】:2021-01-06 12:22:56
【问题描述】:

使用 Laravel 7,我可以上传、添加和删除任务中的所有图像(如果是博客则发布),但我不清楚如何从任务视图(单个帖子视图)中删除单个图像。我正在为任务使用资源控制器,但我认为我需要一个不同的功能。我在同一个 TasksController 中创建了一个,关于资源控制器,我为它创建了一个删除路由。当我单击单个图像删除按钮时,我的应用程序抱怨我试图获取非对象的属性“task_name”。我不知道该怎么做,或者我是否需要创建一个图像控制器(我目前没有使用它)。我将展示我正在尝试的内容,也许,您可以告诉我我是否不在基地或分享一些建议。所以,首先,这是我的 web.php:

<?php

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

Route::get('/users', 'UsersController@index');
Route::delete('delete-image', 'TasksController@delete')->name('delete-image');

Route::resource('tasks', 'TasksController');
Route::resource('users', 'UsersController');

我的 TasksController 显示了我的销毁方法以及我新创建的删除方法:

public function destroy($id)
    {
        $task = Task::with('images')->findOrFail($id);

        foreach ($task->images as $image) {
            Storage::disk('public')->delete('upload/' . $image->name);
        }

        $task->images()->delete();
        $task->delete();
        return redirect('home')->with('success', 'Task Deleted');
    }

    public function delete($id)
    {
        //
        $task = Task::with('images')->findOrFail($id);
        $task->images()->delete();

        $images = Image::find($id);
        Storage::disk('public')->delete('upload/' . $images->name);
        $images->name()->delete();
        return redirect('home')->with('success', 'Task Deleted');
    }

在我的 show.blade.php 中,它将作为单个帖子视图:

<div class="col-md-12">
                <h5>Images</h5>
                <hr />
                  <div class="row">
                      @if($task->images->count()>0)

                          @for($i=0; $i < count($images = $task->images()->get()); $i++)
                          <div class="col-lg-4 col-md-6 col-sm-12">
                            <a href="delete-image" class="badge badge-danger p-2 mb-3">Delete</a><br>
                            <a href="#" class="thumbnail" data-toggle="modal" data-target="#lightbox"><img class="w-50 mb-2" src="/storage/upload/{{ $images[$i]['name'] }}" alt=""></a>

                        </div>

                          @endfor
                          @else
                              <p>No images found</p>
                      @endif
                  </div>
                <br />
              </div>

在我的 Image.php 模型中,我的关系如下:

public function task()
    {
        return $this->belongsTo('App\Task', 'task_id');
        // return $this->belongsTo(Task::class);
    }

    public static function boot()
    {
        parent::boot();
        self::deleting(function ($images) {

            // File::delete(Storage::path($images['name']));
            File::delete(str_replace('\\', '/', storage_path('app/public/upload/' . $images->name)));
        });
    }

在我的 Task.php 模型中:

public function images()
    {
        // return $this->hasMany('App\Image');
        return $this->hasMany(Image::class);
    }

    public static function boot()
    {
        parent::boot();
        self::deleting(function ($task) {
            foreach ($task->image ?: [] as $image) {
                $image->delete();
            }
        });
    }

如果我遗漏了什么,请告诉我,以便我修改我的问题。我真的很感激这方面的帮助,因为我落后了一周。提前谢谢你。

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    您需要传递特定的 image_id 才能将其删除。我还对更简洁的代码进行了一些更改:

    <div class="row">
            @forelse($task->images as $image)
                <div class="col-lg-4 col-md-6 col-sm-12">
                <a href="delete-image/{{$image->id}}" class="badge badge-danger p-2 mb-3">Delete</a><br>
                <a href="#" class="thumbnail" data-toggle="modal" data-target="#lightbox">
                    <img class="w-50 mb-2" src="/storage/upload/{{ $image->name }}" alt=""></a>
            </div>
            @empty
                <p>No images found</p>
            @endforelse
    </div>
    

    请注意,删除按钮现在会将您带到 .../delete-image/{image_id}

    然后在控制器上找到 id 并将其删除。

    更新您的路由文件以接受 id 作为变量

    Route::delete('delete-image/{image_id}', 'TasksController@delete')->name('delete-image');
    

    那么控制器变量可以被访问为

    public function delete($image_id, Request $request)
    {
        # code...
    }
    

    【讨论】:

    • 谢谢哈西尔。我更近了。我无法在我的控制器中找到 id。有什么建议吗?路线不断将我带到 404。我可以看到带有图像 id 的 url。 :public function delete(Image $image) { // // $task = Task::with('images')-&gt;findOrFail($id); $images = Image::find(); foreach ($images as $image) { dd($image-&gt;id); Storage::disk('public')-&gt;delete('upload/' . $image-&gt;name); } $images-&gt;delete(); return redirect('home')-&gt;with('success', 'Image Deleted'); }
    • 谢谢@Hásil。我根据您的建议更改了代码,但我仍然得到一个 404 页面,就好像它没有找到控制器一样。两件事,我想知道,第一,图像与其任务有关系的事实,这就是为什么或者我的图像表中没有 image_id 的原因。我很茫然。很抱歉成为害虫。
    • 谢谢@Hásil。我得到了要从磁盘和数据库中删除的图像。剩下的唯一一件事是,在实施您建议的代码后,我看不到我的图像。如果我使用&lt;img src="/storage/upload/{{$image-&gt;name}}"&gt;,我会收到错误消息“Property [name] does not exist on this collection”。有什么线索吗?再次感谢
    • 要么 $image 对象不包含 name 键,要么 $image 是一个数组。首先,dd($image) 并检查 name 是否存在,然后尝试 $image['name']。我还建议使用 laravel 上可用的asset() 函数来获取准确的网址。 name) }}" >
    • 谢谢@Hásil。这就是问题所在。我将图像标签更改为:&lt;img src="/storage/upload/{{ $images[$i]['name'] }}" class="w-50 mb-2" alt=""&gt; 现在已修复。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多