Releases: ahmadhuss/laravel-work
Configuration Production
Product Photo Upload
Now, We can upload a photo for the product, and a validation rule has been added.
$path = $request->file('photo')->store('photos', 'public');
Validation rule:
'photo' => 'required|image|mimes:jpeg,png,jpg|max:2048',
Storage Strategy because of this :
$path = $request->file('photo')->store('photos', 'public');
We are storing an uploaded photo in the storage/app/public/photos
directory and photo saved in the database with the following path photos/${imagePath}.jpg
.
After that, we have used the artisan
CLI and made the symlink (shortcut) of the storage/app/public
directory to /public/storage
.
Finally, we can publicly access photos in blade with following syntax asset("storage/$product->photo")
.
Validation Strategies & Route Group
Here we deal with the validation with 2 methods inside the store
function which will be invoked when the user wants to create the new Product.
- Using default
Request $request
dependency injection and invoke the validate method.
public function store(Request $request)
{
// If validation fails it will redirect back to same form.
$request->validate([
'name' => 'required',
'price' => 'required|decimal',
]);
Product::create([
'name' => $request->name,
'price' => $request->price,
'category_id' => $request->category_id,
'description' => $request->description,
'photo' => ''
]);
return redirect()->route('products.index');
}
- Create the Request class with
artisan
and inside the method of this class namedrules
define all your validation rules and used this as a dependency injection inside thestore
function.
php artisan make:request StoreProductRequest
class StoreProductRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required',
'price' => 'required|decimal',
];
}
}
public function store(StoreProductRequest $request)
{
Product::create([
'name' => $request->name,
'price' => $request->price,
'category_id' => $request->category_id,
'description' => $request->description,
'photo' => ''
]);
return redirect()->route('products.index');
}
ProductController Management
In this version, we created the ProductController
with the help of artisan
resource command flag and added logic for all these methods. So far we created the CRUD functionality 2 times. One for Category and the other for the Product.
CategoryController Management
php artisan make:controller CategoryController --resource
Route:
Route::resource('/categories', CategoryController::class)->middleware('auth');
The resource controller has 7 methods.
- index (list all categories)
- create (to create category)
- store (store to process the form)
- Show (to show individual category)
- edit (for edit category)
- update (process the edit form)
- destroy (delete the record)
Now we can reference something like this in our views.
<td>
<a class="btn btn-primary" href="{{ route('categories.edit', $category->id) }}">Edit</a>
</td>
Laravel UI Auth Scaffold & Seeder
We used a package named laravel/ui
to create the Auth scaffolding. Because default Auth scaffolding was removed from Laravel v7
and it comes to only earlier versions.
php artisan ui bootstrap --auth
We also created the seeder class.
php artisan make:seeder UserSeeder
Behind the scenes, we have ignored the Model factories and instead used the additional Seeder class named UserSeeder.php
and put user credentials inside the run()
method of this class. Now when we enter the command.
php artisan db:seed
db:seed
will execute run()
method of DatabaseSeeder.php
class and this method will bootstrap our UserSeeder.php
class.
DatabaseSeeder.php
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call([UserSeeder::class]);
}
}
Database Product Relationship
- Created the
Product
Model with migration - To use a modifying column with migration, we installed a package named
doctrine/dbal
- Added foreign key field in
Product
table with the help of 2 lines in migration as we know foreign key always take reference from the other table - In the
Product
Model we created a relationship withbelongsTo
function
class Product extends Model
{
use HasFactory;
// Create relationship of 1 to 1 with Category Model (Category::class)
public function category()
{
return $this->belongsTo(Category::class);
}
}
- Render product category inside the view with
<h1>{{ $product->category->name }}</h1>
- For performance reason we are adding condition with the help of
with()
method to load the relationship inside the Controller
$allCategories = Category::all();
$allProducts = Product::with('category')->get();
Database Migration & Model View Controller
Model:
- A Model is a file that describes 1 database table.
- It should be a singular form of the database table.
- It extends the
Model
class means it ties to the Database and ready to use.
class Category extends Model
{
use HasFactory;
}
Controller:
- It is a bridge that gets data from the database and passed it into the views.
- It also takes data from the view (shape of HTML Forms) and stored in the data.
class HomeController extends Controller
{
public function index()
{
// This will get all the records from the categories table
// and every record is an object and passed into the view
$allCategories = Category::all();
return view('index', compact('allCategories'));
}
}
View:
- Represents presentation layer of our application.
<div class="list-group">
@foreach($allCategories as $category)
<a href="/?category_id={{ $category->id }}" class="list-group-item">{{ $category->name }}</a>
@endforeach
</div>
Initial Release
- Static template conversion into Blade 👍