Home > Software engineering >  How can I solve an image add issue on Laravel 8?
How can I solve an image add issue on Laravel 8?

Time:01-18

I have an issue with my Laravel8 project.

In my project, a user can post an add with an image. The image is well saved in the database but it's not displaying. And on my Console, I do have a 404 error message.

404 error message

Here is my code in my migration file :

    <?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddColumnImageUrlToOffersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('offers', function (Blueprint $table) {
            //store images
            $table->string('image_url');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('offers', function (Blueprint $table) {
            //drop the columns
            $table->dropColumn('image_url');
        });
    }
}

Here is my code in my layout file :

            <div >
            <img  src="{{asset($offer->image_url)}}" alt="" srcset="">
        </div>

Thanks for your help

CodePudding user response:

Here is my Controller code :

    <?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Offer;
use Illuminate\Support\Facades\Auth;


class OffersController extends Controller
{

    //fetch the offers
    public function index()
    {
        $offers=Offer::orderBy('created_at', 'desc')->paginate(16);//return a collection ordered by date
        return view('offers')->with('offers', $offers);
    }

    //fetch own Offers
    public function showOwnOffers()
    {
        $offers = Offer::where('user_id', Auth::id())->orderBy('created_at', 'desc')->get();
        return view('dashboard')->with('offers', $offers);
    }

    //Fetch an offer by id reset
    public function show($id){
        $offer=Offer::find($id);
        return view('offer')->with('offer', $offer);
    }
    
    //Store products info on the database
    public function store(Request $request) {
        echo "Inside OffersController , store()";
    
    //validate the inputs
    $request->validate([
        'title' =>'required',
        'city' => 'required',
        'people' => 'required',
        'desc-full' => 'required',
        'rent'=> 'required | numeric',
        'img' => 'required'
    ], [
        'title.required' => 'Saisissez un titre',
        'city.required' => 'Saisissez une ville',
        'people.required' => 'Saisissez le nombre de collocataires',
        'desc-full.required' => 'Décrivez la colocation',
        'rent.required' => 'Entrez un loyer',
        'img.required' => 'Enregistrez une image',
    ], 
    [
        'title' => 'titre de l\'annonce',
        'city' => 'ville',
        'people' => 'nombre de colocataires',
        'desc-full' => 'description',
        'img' => 'image',
        'rent'=> 'loyer'
    ]);
    //upload the img
    $path=$request->file('img')->store('offer_images');
    // dd($path);
    //Insert data into the products table
    $offer=new Offer();
    $offer->title=$request->input('title');
    $offer->city=$request->input('city');
    $offer->people=$request->input('people');
    $offer->long_desc=$request->input('desc-full');
    $offer->image_url=$path;
    $offer->user_id=Auth::id();
    $offer->rent=$request->input('rent');

    $offer->save();

    return redirect('/offer/'.$offer->id);
    }

    //function to edit offer
    public function edit($id) {
    $offer=Offer::find($id);
    return view('edit')->with('offer',$offer);
    }

    public function update(Request $request, $id) {
        $request->validate([
            'rent' =>'numeric'
        ]);
        // get product by id
        $offer=Offer::find($id);

        if($request->hasFile('img'))
        {
            $path = $request->file('img')->store('offer_images');
        }

        // check if inputs are empty
        if(!empty($request->input('title')))
        {
            $offer->title = $request->input('title');
        }

        if(!empty($request->input('city')))
        {
            $offer->city = $request->input('city');
        }

        if(!empty($request->input('people')))
        {
            $offer->people = $request->input('people');
        }

        if(!empty($request->input('desc-full')))
        {
            $offer->long_desc = $request->input('desc-full');
        }

        if(!empty($request->input('rent')))
        {
            $offer->rent = $request->input('rent');
        }

        // save changes
        $offer->save();
        return redirect('/offer/'.$offer->id);
    }

        // function to delete an offer
        public function destroy($id)
        {
            $offer=Offer::find($id);
            $offer->delete();
            return redirect()->action([OffersController::class,'showOwnOffers']);
        }
}

My images are stored on public>offer_images

Thanks for your help

CodePudding user response:

I could give you more info if you were to include the controller file, but usually, when you save a file via controller, it usually saves on storage folder on public directory. In simple terms, you probably need to do something like :

<img  src="{{asset('/storage/' . $offer->image_url)}}" alt="" srcset="">

If this does not work, please update the post with controller code, so we can check how you're storing the image. If you're feeling adventurous, feel free to take a look at storage folder on public directory any see if you can figure out what the appropriate url should be

Update: After looking at your controller it seems like you're not storing the image in the [public disk][1]. By default laravel sores the files in private disk. To store the image to public disk, simply rewrite the $path like this: $path=$request->file('img')->store('offer_images', 'public'); //Public being the name of disk

Now run php artisan storage:link if you haven't already. Once that is done, the following code should work perfectly

<img  src="{{asset('/storage/' . $offer->image_url)}}" alt="" srcset="">

Note: Laravel stores the image in /storage/app/public when you specify public disk as your storage. The folder is the linked to /public/storage. That is why you have to prefix the image url with /storage/ [1]: https://laravel.com/docs/8.x/filesystem#the-public-disk

CodePudding user response:

Check your storage folder permissions
if you are on localhost try 777
if you are on server you can try 755

Create symbolic link

php artisan storage:link

Specify a public disk, example

$path = $request->file('file')->store(
    'offer_images/'.$request->user()->id, 'public'
);

Retrieve file

$url = Storage::url('file.jpg');

Since you are getting 404 Not Found try retrieving file with domain

$url = env('APP_URL').Storage::url('file.jpg');
  •  Tags:  
  • Related