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.
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');

