Uploading images in Laravel 6

So,

this time I had a problem with the upload of the images and I had a time thanks to Corona break from my main work to learn it. Well, I would do it anyway, but I could do it quicker. So, here is in the steps how I achieved it.

First, I already know how to quickly create CRUD/Bread. So, we need a model, migration, controller and view Blade pages with Routes. If someone doesn't know how to do it, all those details are on this blog. The blog is mainly for me so that I can save time next time when I'll do the same thing from scratch.

I like to test things after let say creating crud, so I've started from a post and image upload with echo function so that I can see that Lara is pulling everything the right way:

<form action="/ingredients" method="POST" enctype="multipart/form-data">
{{ csrf_field() }}
<input type="text" name="name" placeholder="Name" class="form-control"><br><br>
<input type="text" name="qty" placeholder="Qty" class="form-control"><br><br>
<input type="text" name="unit" placeholder="Unit" class="form-control"><br><br>
<input type="file" name="image" id="photo" class="form-control-file"><br><br>
<button type="submit" class="btn btn-primary"> Submit</button>
</form>

This was the form that I've created, only with Polish names in the Placeholders.

My code in the controller was:

public function store(Request $request)
{
    $validatedData = request()->validate([
    'name' => 'required',
    'image' => 'required',
]);

\App\Post::create($validatedData);
echo $request->file('image')->store('public');
}

I had a post model anyway with controller and I knew this one is working, so I've used that to make my first test ;). My outcome in the browser was successful:

public/X1TIoEFjIATdBXpN1X7W7WZahkSON0H7tjPAKrhE.jpeg

But, if you didn't have a model you can use this one as an example:

class ingredient extends Model
{
//Belongs to many to many group/model: ingr_lists.

public function roles()
{
return $this->belongsToMany('App\ingr_list');
}

protected $fillable = ['unit', 'foo', 'bar'];
protected $guarded = [];
}

unit, foo and bar are just examples and should be columns in your DB.

I've finished my ingredients CRUD without an image upload cause I've never done it in the past ;) on my own and tutorials didn't help. So, I've started to watch a few tutorials and verify with Laravel 6 documentation. This leads me to my success!

Once I had it with echo, I know I won :). So, I've used my Ingredients Controller and just add ->store('public') to my existing function in the image field. So, here is how my controller looks now with a proper setup:

 public function create()
    {
        return view('ingredients.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
        
    {
        $this->validate($request,[
          
            'name' => 'required',
            'image' => 'required',
        ]);


        //Create new Ingredient
        $ingredients = new ingredient;
        $ingredients->name = $request->input('name');
        $ingredients->unit = $request->input('unit');
        $ingredients->qty = $request->input('qty');
        $ingredients->image = $request->file('image')->store('public');
     
        $ingredients->save();
             
        return redirect('/ingredients')->with('success', 'Dodano do Bazy');
      
    }

I did not have to change my form, nor anything else :) because I've already added file upload to my form.


I'm still learning Lara, so I'm using Bootstrap to quickly create a design. Content is in Polish, but I've put in placeholders' names of the fields. You can see that there is a file upload and I've inserted one already. Zapisz button is just a Save/Submit.


After clicking on Submit we can see that those details are in the index.blade.php shown in our table as Name, Qty, Unit. Next is the DB view of how images look there:


So, that's it ;). I can successfully upload images in Laravel 6. The last step is to display such an image in my View Page, or on the top of that to display a thumbnail in the list/table view.

The line of the code which finally worked for me after 2 days of research and asking experts in the Facebook group came like this:

<img src="{{ Storage::url($ingredient->image) }}" width="500" height="333">

Of course, you don't need width, nor the height to display it the right way, but it was just too big on my screen ;) and hence for that, I've done it. I share VS Code, web browser and something else on my screen and it's OK on 34" which I bought to learn to program, but when I Inspect an element it's still no WOW for me and I don't want to switch on another screen ;). I'd rather change size of the image :).

But, let's go back to how I've done it. I did as well this command:

php artisan storage:link

From my understanding this will change the code in filesystems.php in a config folder to app/public like here:

'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],


And, this will allow you to use a folder as a storage for all your uploads. No point to just change this code, tried that :). There has to be more to it, either recompile the app if I can call it like that or other places where you can make the change.

There are other ways as always in Laravel to achieve showing the images, but I did want to avoid the work with a controller ;). So, this was making more sense in my head :).

Now, I have no problem with showing images in my show.blade.php, or any other file out there.








No comments:

Post a Comment