1. Tổng quan
a/ CRUD là gì?
CRUD là chữ viết tắt của Create – Read – Update – Delete.
- Create: là tính năng tạo một record mới trong bảng dữ liệu. Tính năng Create là tên chung, gồm 2 phần: create là chức năng hiển thị form nhập liệu và store là chức năng lưu nội dung nhập từ form thành một record mới trong bảng dữ liệu.
- Read: là tính năng hiển thị nội dung của một hay nhiều record trong bảng dữ liệu. Nó cũng gồm 2 phần: index là chức năng hiển thị nhiều record và show là chức năng hiển thị một record được chỉ định. Ở một tính năng của phần mềm, index thường là chức năng mặc định khi người dùng truy cập vào tính năng đó.
- Update: là tính năng sửa chữa nội dung một record dữ liệu được chỉ định. Nó cũng gồm 2 phần: edit là chức năng hiển thị lại form nhập liệu có kèm theo nội dung cũ cần sửa và update là chức năng lưu nội dung trong form (đã được người dùng sửa chữa) vào cơ sở dữ liệu tại record được chỉ định.
- Delete: là tính năng xóa record dữ liệu được chỉ định. Tính năng này cũng gồm 2 phần: confirm là chức năng xác nhận với người dùng xem có thực sự muốn xóa không hay chỉ bấm nhầm và destroy là chức năng thực hiện xóa record trong bảng dữ liệu.
b/ Parent table và Child table
Trong cơ sở dữ liệu có nhiều bảng dữ liệu, các bảng dữ liệu thường được thiết kế có quan hệ với nhau bằng cách liên kết khóa ngoại. Có loại bảng đi liên kết và bảng được liên kết, bảng được liên kết sẽ có khóa chính trở thành khóa ngoại trong bảng đi liên kết. Bảng được liên kết tạm gọi là parent table (bảng cha) và bảng đi liên kết tạm gọi là child table (bảng con). Một bảng có thể bảng cha trong mối quan hệ với bảng này, nhưng có thể trở thành bảng con trong mối quan hệ với bảng khác.
Tuy nhiên, có một loại bảng luôn là bảng cha trong tất cả các mối quan hệ với bảng khác, tạm gọi là bảng dữ liệu cơ bản. Do không có liên kết dữ liệu với bảng khác nên việc triển khai CRUD cho loại bảng dữ liệu cơ bản này tương đối đơn giản.
Trong dự án thực hành cho loạt bài viết này, bảng bans được coi là bảng cha và là bảng dữ liệu cơ bản, bảng nhanviens là bảng con vì trong cấu trúc của nó có trường ID của Ban liên kết khóa ngoại với trường ID của bảng bans. Vì bảng bans triển khai CRUD đơn giản hơn nên chúng ta thực hiện trước để hiểu cách làm các tính năng CRUD.
2. Tạo model và controller bằng lệnh artisan
Để bắt đầu triển khai các tính năng CRUD cho bảng bans chúng ta cần tạo model và controller cho nó. Laravel cung cấp công cụ dòng lệnh artisan để lập trình viên dễ dàng nhanh chóng tạo các thành phần này.
Mở CMD tại thư mục gốc của dự án và gõ 2 lệnh sau:
php artisan make:model Ban php artisan make:controller BanController --resource

Chú thích:
- Lệnh số 1: tạo model Ban. Tên model là cách viết ngữ pháp số ít của tên bảng dữ liệu (trong tiếng Anh) và viết theo định dạng camelCase (nếu chữ hoa ở đầu thì hay gọi là PascalCase). Model được tạo ra là model Eloquent ORM, một trong những đặc trưng của Laravel.
- Lệnh số 2: tạo controller có tên BanController. Tên controller thường được đặt bằng cách ghép tên model với cụm ký tự Controller (chữ C viết hoa).
- Tùy chọn –resource hay -r trong lệnh số 2: tự động tạo form mẫu của 7 phương thức cơ bản cho các tính năng CRUD gồm: index(), show(), create(), store(), edit(), update(), destroy() trong controller vừa tạo ra. Có thể bỏ tùy chọn này và lập trình viên sẽ tự tạo method khi viết mã. Riêng chức năng confirm của tính năng Delete sẽ dùng JavaScript xử lý tại trình duyệt nên không tạo phương thức ở đây.

Code của Ban.php sau khi được tạo tự động bằng lệnh:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Ban extends Model { //protected $table = 'bans'; /* vì đã đặt tên model đúng theo quy định nên hệ thống tự động liên kết với bảng dữ liệu, không cần khai báo biến $table */ }
Code của BanController.php sau khi được tạo tự động bằng lệnh (phía trên các method đều có chú thích bằng tiếng Anh khá rõ):
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class BanController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { // } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { // } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { // } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { // } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { // } }
Chú ý:
Trong thực tế, lập trình viên sẽ không gõ các lệnh artisan riêng biệt mà chỉ gõ 1 lệnh với các tùy chọn để tạo ra model, migration, controller, factory (công cụ tạo dữ liệu giả).
php artisan make:model Ban -m -c -r -f
- Lệnh artisan bên trên chức năng chính là tạo ra một model có tên là Ban.
- Tùy chọn -m (–migration): tạo ra file migration đi kèm với model.
- Tùy chọn -c (–controller): tạo ra file BanController.php
- Tùy chọn -r (–resources): tạo ra 7 method CRUD cơ bản trong BanController.php
- Tùy chọn -f (–factory): tạo ra BanFactory.php – công cụ để tạo dữ liệu giả hàng loạt cho bảng bans. Bạn có thể không dùng tính năng này vì có thể nhập tay hoặc dùng công cụ khác.
3. Mẫu bố cục giao diện web (layout) và Blade template engine
a/ Tổng quan
Một trang web hoặc giao diện của phần mềm nền web sẽ dùng trình duyệt web tải xuống mã HTML – CSS – Javascript – hình ảnh để hiển thị cho người dùng xem và tương tác.
Trong mã HTML tải xuống có một bố cục (layout) giống nhau ở nhiều trang như tag <html>, tag <head>, tag <body>, tag <title>, thiết kế dàn trang , thiết kế phần header trang, thiết kế phần footer trang, thiết kế menu chung … Vì vậy, lập trình viên có nhu cầu tạo 1 file layout chung có thể dùng ở các trang khác nhau để không phải viết lặp lại và khi sửa thì chỉ sửa trong một file áp dụng cho tất cả.
Tuy bố cục giống nhau nhưng nội dung hiển thị và một số đoạn mã chèn vào giữa lại khác nhau ở mỗi trang, thậm chí ở một số vị trí còn cần phải chèn mã lập trình PHP vào để xử lý ở server trước khi gửi xuống client. Từ đó phát sinh nhu cầu cần có công cụ chuyên dụng để thực hiện việc xử lý giao diện hiển thị này, đó chính là các template engine. Laravel sử dụng Blade template engine, đây là công cụ đặc trưng của Laravel.
b/ Trang layout tổng quát
Trang layout tổng quát được dàn trang đầy đủ, chưa tách ra thành các file nhỏ. File này được đặt tên là layout.blade.php (chú ý: đuôi .blade.php là cách đặt tên của Blade template engine). File được lưu tại thư mục /resources/views. Để tạo file blade, lập trình viên dùng IDE (PHPStorm, Sublime Text, Visual Studio Code…) để tạo file .php, đặt tên và lưu đúng nơi quy định. Các vị trí có chú thích <!–chèn … chổ này–> thì chúng ta sẽ dùng cú pháp của Blade để thay thế, mục tiêu nhằm tùy biến code tại vị trí đó ở các trang khác nhau. Riêng vị trí chèn menu, vì dự án này đơn giản nên không tách phần menu ra mà viết trực tiếp vào layout, nhưng hiện giờ vẫn chưa xác định đủ các thành phần menu nên chúng ta để trống chổ đó và phát triển dần dần.
<!DOCTYPE html> <html lang="vi"> <head> <meta charset="UTF-8"> <title> <!--chèn tiêu đề trang chổ này--> </title> </head> <body> <table style="width:100%; border: 0;"> <tr> <th style="width:20%;"> <h2>Tổng Trạm<br > HOÀNG HOA THÁM</h2></th> <th style="width:80%;"> <h2>QUẢN LÝ NHÂN SỰ TỔNG TRẠM</h2></th> </tr> <tr> <td style="height:650px; vertical-align: top;"> <h3>Menu</h3> <!--chèn menu chổ này--> </td> <td style="vertical-align: top;"> <h2><!--chèn tên trang cỡ chữ lớn chổ này--></h2> <div> <!--toàn bộ nội dung trang sẽ đặt chổ này--> </div> </td> </tr> <tr> <td>UBM Co., Ltd</td> <td>Training Laravel phần 3</td> </tr> </table> </body> </html>
c/ Cú pháp extends, yield và section trong Blade
Để sử dụng được layout đó trong các trang con kết thừa thì chúng ta sử dụng cú pháp extends ở đầu file blade con, đồng thời phải sử dụng 2 cú pháp khác là yield và section mới tùy biến được nội dung cho trang con.
- Cú pháp extends: được sử dụng để import file layout vào file blade con, cú pháp này viết ở đầu file blade con. Cách viết như sau: @extends(‘layout’), trong đó, layout là tên của file blade cần import.
- Cú pháp yield: được sử dụng để định vị trí tùy biến ở trang layout, mỗi vị trí trong file layout sẽ được đặt một tên để nhận diện. Ví dụ: ở vị trí tiêu đề trang <!–chèn tiêu đề trang chổ này–> sẽ có 1 yield có tên ‘title‘ để nhận diện vị trí này, cách viết như sau: @yield(‘title’)
- Cú pháp section: được sử dụng ở trang blade con để gán nội dung vào vị trí mà cú pháp yield đã đặt tên nhận diện trên trang layout. Có 2 cách viết section: nội dung trên một dòng hoặc nội dung trên nhiều dòng. Ví dụ:
+ Nội dung trên một dòng: @section(‘title’,’Quản Lý Nhân Sự Tổng Trạm’)
+ Nội dung trên nhiều dòng:
@section(‘pageCss’)
//CSS
@endsection
Nội dung trên nhiều dòng phải dùng cú pháp @endsection để kết thúc phần nội dung.
d/ Tạo trang blade cho dashboard
Trang dashboard là trang mặc định hiển thị khi người dùng truy cập vào phần mềm (tương tự trang chủ web). Ở dự án thực hành này không cần thiết phải có trang dashboard nhưng chúng ta tạo một trang mô phỏng cho giống thực tế. Nội dung của trang chỉ ghi vài câu gì đó để cho người dùng biết đang truy cập vào trang dashboard.
Để tạo trang dashboard chúng ta cần làm 2 việc đó là:
- Hoàn thiện trang layout (thêm yield ở các vị trí cần thiết).
- Tạo file dashboard.blade.php kế thừa layout và dùng các section để thêm nội dung cho trang dashboard.
File layout.blade.php sau khi thêm yield có nội dung như sau:
<!DOCTYPE html> <html lang="vi"> <head> <meta charset="UTF-8"> <title> @yield('title') </title> </head> <body> <table style="width:100%; border: 0;"> <tr> <th style="width:20%;"> <h2>Tổng Trạm<br > HOÀNG HOA THÁM</h2></th> <th style="width:80%;"> <h2>QUẢN LÝ NHÂN SỰ TỔNG TRẠM</h2></th> </tr> <tr> <td style="height:650px; vertical-align: top;"> <h3>Menu</h3> <!--chèn menu chổ này--> </td> <td style="vertical-align: top;"> <h2>@yield('bigTitle')</h2> <div> @yield('content') </div> </td> </tr> <tr> <td>UBM Co., Ltd</td> <td>Training Laravel phần 3</td> </tr> </table> </body> </html>
Tạo file dashboard.blade.php và sau khi thiết lập các dòng lệnh extends và section thì có nội dung như sau:
@extends('layout') @section('title','Dashboard - Quản Lý Nhân Sự Tổng Trạm') @section('bigTitle','DASHBOARD') @section('content') <h3>Đây là trang Dashboard của phần mềm Quản Lý Nhân Sự Tổng Trạm</h3> <h4>Trang Dashboard là trang mặc định của phần mềm, tương tự trang chủ website</h4> @endsection
4. Triển khai trang Dashboard
Mục trước chúng ta đã thực hiện xong phần views cho trang Dashboard, ở mục này, chúng ta sẽ triển khai trang Dashboard này để người dùng truy cập vào.
Muốn triển khai một trang cần làm các việc sau:
- Tạo controller và method bên trong nó để xử lý request.
- Tạo route để định tuyến request vào method trong controller.
- Trong method của controller gọi view (lấy nội dung từ file blade) và truyền data qua view để hiển thị ra ở trình duyệt người dùng.
Bước 1: Tạo controller và method
Mở CMD tại thư mục gốc của dự án và gõ lệnh sau:
php artisan make:controller DashboardController
Lệnh trên sẽ tạo ra một file controller có tên DashboardController.php. Mở file này trong IDE và tạo thêm method có tên index() để chuẩn bị xử lý hiển thị view trang dashboard. Nội dung file DashboardController.php sẽ như sau:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class DashboardController extends Controller { public function index() { } }
Bước 2: Tạo route
Để có thể chạy được method index() trong DashboardController chúng ta cần tạo route đến method này. Mở file /routes/web.php, xóa hết nội dung đã có và thêm dòng sau:
Route::get('/','DashboardController@index')->name('dashboard');
Dòng mã trên dùng để định tuyến trang chủ của phần mềm vào method index() của DashboardController và đặt tên cho tuyến đường này là ‘dashboard’. Sau này, ở bất cứ vị trí nào của dự án chúng ta cũng có thể gọi ra tuyến đường này bằng cách gọi tên đã đặt. Lúc này nội dung file /routes/web.php như sau:
<?php Route::get('/','DashboardController@index')->name('dashboard');
Bước 3: Xử lý trong method index() của DashboardController
Đến lúc này thì người dùng có thể truy cập vào trang chủ của phần mềm nhưng sẽ nhận được một trang trắng vì chúng ta chưa xử lý gì ở method index(). Vì dashboard này chỉ hiển thị đơn giản nên chúng ta không xử lý gì ở đây, chỉ đơn thuần là gọi view để trả lại giao diện hiển thị trên trình duyệt người dùng mà thôi. Cách gọi view mời xem nội dung file DashboardController.php bên dưới.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class DashboardController extends Controller { public function index() { return view('dashboard'); } }
Kết quả hiển thị ở trình duyệt người dùng

5. Triển khai tính năng Create
…
6. Triển khai tính năng Read
…
7. Triển khai tính năng Update
…
8. Triển khai tính năng Delete
…