CHƯƠNG 4 : TƯƠNG TÁC DATABASE VỚI ELOQUENT ORM
4.1 TỔNG QUAN Error! Bookmark not defined.
4.1.3. XÓA DỮ LIỆU
Tương tự như cập nhật dữ liệu, xóa dữ liệu cũng phải tìm ra được dịng cần xóa và gọi đến phương thức delete
Ví dụ 7: Xóa dịng dữ liệu có id = 1
Ngồi ra, Eloquent cịn cung cấp cơ chế cho phép xóa nhiều dịng dữ liệu với điều kiện cho trước
Ví dụ 8: Xóa dịng dữ liệu với điều kiện cho trước
$flight = App\Flight::find(1); $flight->name = 'New Flight Name'; $flight->save();
$flight = App\Flight::find(1); $flight->name = 'New Flight Name'; $flight->delete();
4.2 RELATIONSHIPS
Các bảng trong cơ sở dữ liệu thường có mối quan hệ lẫn nhau. Ví dụ: một blog (bảng blog) có thể có nhiều bình luận (bảng comments).
Có ba mối quan hệ chính giữa các bảng
o One to one o One to many o Many to many
4.2.1. ONE TO ONE
Đây là mối quan hệ 1:1, ví dụ 1 người có 1 mã số chứng minh nhân dân. Hoặc là 1 người dùng 1 số điện thoại
Ví dụ 1: User – Phone
<?php
namespace App;
use Illuminate\Database\Eloquent\Model; class User extends Model{
public function phone(){
return $this->hasOne('App\Phone'); }
4.2.2. ONE TO MANY
Mối quan hệ này trong trường hợp 1 model quan hệ với nhiều dòng trong 1 model khác. Ví dụ 1 bài post có nhiều bình luận (comment)
Ví dụ 2: Một bài post có nhiều bình luận (comment)
<?php
namespace App;
use Illuminate\Database\Eloquent\Model; class Post extends Model
{
public function comments() {
return $this->hasMany('App\Comment'); } } <?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model{
public function post() {
return $this->belongsTo('App\Post'); }
4.2.3. MANY TO MANY
Là mối quan hệ phức tạp hơn one-to-one, one-to-many. Ví dụ một user có nhiều quyền (role), một role cũng có nhiều user. Như vậy, sẽ có ba bảng dữ liệu: users, roles,
role_user.
Việc khai báo mối quan hệ cũng hoàn toàn tương tự:
+ Định nghĩa phương thức roles trong User model
+ Định nghĩa phương thức usres trong Role model
<?php namespace App;
use Illuminate\Database\Eloquent\Model; class Role extends Model{
public function users(){
return $this->belongsToMany('App\User'); } } <?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model {
public function roles(){
return $this->belongsToMany('App\Role'); }
4.3 COLLECTIONS
Cung cấp nhiều thư viện tích hợp để xử lý database, nhằm giảm thời gian phát triển của lập trình viên.
Ví dụ khi truy vấn dữ liệu, kết quả trả về là json. Cấu trúc gọi hoàn toàn tương tự như hàm all, get
Phương thức: sortBy sắp xếp
Phương thức sum tính kết quả trả về Phương thức count: đếm số kết quả trả về
all diffAssoc keyBy only sort
average diffKeys keys pad sortBy
avg dump last partition sortByDesc
chunk duplicates macro pipe sortDesc
collapse duplicatesStrict make pluck sortKeys
collect each map pop sortKeysDesc
combine eachSpread mapInto prepend splice
concat every mapSpread pull split
contains except mapToGroups push sum
containsStrict filter mapWithKeys put take
count first max random takeUntil
4.4 MUTATORS
Accessors và Mutators cho phép định dạng các thuộc tính dữ liệu trong Eloquent khi lấy ra hay thiết lập các giá trị trong model. Ví dụ: mã hóa ngày tháng khi lưu vào database, giải mã ngày tháng khi lấy ra. Việc này giúp ích cho hệ thống có cùng định dạng ngày tháng, giúp cho việc tìm kiếm ngày tháng sẽ nhanh hơn.
Accessors sẽ tự động được gọi bởi Eloquent khi “lấy ra” giá trị của thuộc tính.
Mutators sẽ tự động được gọi bởi Eloquent khi “thiết lập” giá trị của thuộc tính.
4.4.1. ĐỊNH NGHĨA ACCESSOR
Để định nghĩa một accessor
Bước 1: Khai báo hàm getFooAttribute trong model, trong đó Foo là tên cột Bước 2: Hiện thực hàm
Ví dụ 1: Định nghĩa hàm getFirstNameAttribute cho cột first_name trong bảng user
như sau:
<?php namespace App;
use Illuminate\Database\Eloquent\Model; class User extends Model{
public function getFirstNameAttribute($value){ return ucfirst($value);
} }
Quy cách đặt tên cột trong bảng được đề nghị là: chữ thường, nếu có từ 2 từ trở lên sẽ được ngăn cách bởi dấu “_”. Khi đó, hàm accessor sẽ được viết hoa từ đầu của từ trong tên cột.
Trở lại ví dụ trên, khi truy vấn giá trị của cột first_name, hàm getFirstName sẽ được gọi. Giá trị truyền vào hàm là giá trị của cột first_name, hàm sẽ xử lý và trả về giá trị mới.
Ví dụ 2: Truy vấn giá trị first_name sau khi đã khai báo accessor
4.4.2. ĐỊNH NGHĨA MUTATORS
Tương tự như accessor, khai báo mutator như sau:
Bước 1: Khai báo hàm setFooAttribute trong model, trong đó Foo là tên cột Bước 2: Hiện thực hàm
Hàm mutator sẽ được gọi khi thiết lập giá trị cho cột trong model
Ví dụ 3: Thiết lập giá trị first_name sử dụng mutator
$user = App\User::find(1); $firstName = $user->first_name;
<?php namespace App;
use Illuminate\Database\Eloquent\Model; class User extends Model{
public function setFirstNameAttribute($value) {
$this->attributes['first_name'] = strtolower($value); }
Hàm mutator sẽ nhận giá trị chuẩn bị lưu vào cơ sở dữ liệu, tiến hành xử lý và thiết lập giá trị.
Ví dụ 4: Sử dụng sau khi đã thiết lập mutator
4.5 SERIALIZATION
Khi xây dựng JSON APIs, Eloquent cung cấp các phương thức để chuyển model thành JSON hay array.
Sử dụng phương thức toArray() để chuyển model thành array, đây là một phương thức đệ quy nên tất cả các thuộc tính và mối quan hệ sẽ được chuyển thành array.
Ví dụ 1: Chuyển thành array của user model
Tương tự, sử dụng phương thức toJson() để chuyển model thành array, đây cũng là phương thức đệ quy nên tất cả các thuộc tính và mối quan hệ sẽ được chuyển thành JSON.
Ví dụ 2: Chuyển thành JSON của user model
4.6 BÀI TẬP
Bài 1: Tiếp tục phát triển lược đồ cơ sở dữ liệu từ mục 3.5
Cho database schema như hình sau (chưa bao gồm các thiết kế trong mục 3.5) $user = App\User::find(1); $user->first_name = 'Sally'; $user = App\User::with('roles')->first(); return $user->toArray(); $user = App\User::find(1); return $user->toJson();
Hình 4- 3 Lược đồ cơ sở dữ liệu
a) Dùng migration thiết kế cấu trúc bảng trên
b) Dùng seeder tạo một triệu users, 50 groups, 500 permissions
Bài 2: Truy vấn dữ liệu được hiện thực trong các model tương ứng với các bảng
a) Kiểm tra quyền hạn của 1 user b) Hiển thị danh sách quyền của 1 user
Bài 3: Tiếp tục phát triển database với yêu cầu mới như sau
* Bảng provinces: mô tả thông tin tỉnh * Bảng districts: mô tả thông tin quận * Bảng wards: mô tả thông tin phường * Bảng streets: mô tả thông tin đường
* Bảng projects: mô tả thông tin dự án chung cư
a) Sử dụng mối quan hệ one-to-many để truy vấn các districts của 1 provinces
a1). Liệt kê các districts sắp xếp theo Alphabet a2). Kết quả trả về dạng jSon
b) Sử dụng mối quan hệ one-to-many để liệt kê các projects của 1
districts
CHƯƠNG 5: XÁC THỰC NGƯỜI DÙNG Giới thiệu
Xác nhận thông tin người dùng để xác định là thành viên của hệ thống hay khách truy cập bên ngồi là tính năng tất yếu và phải có của hầu hết các website.
Khi đã xác định được thành viên của hệ thống thơng qua hình thức đăng nhập, hệ thống sẽ phân quyền để xác định thành viên và các quyền hạn cho phép.
Laravel cung cấp giải pháp xác thực và phân quyền mang tính bảo mật cao, cấu trúc đơn giản.
- Cách tiếp cận nhanh với ứng dụng xác thực đã được hiện thực thông qua 2 câu lệnh: “php artisan make:auth”, “php artisan migrate”để có được trải nghiệm.
- Cung cấp cách cấu hình bên ngồi core (config/auth.php) giúp việc cấu hình trở nên thuận lợi hơn. Hai cấu hình mẫu đã được cung cấp: “guards”, “providers”.
- “Guards” cho biết cách thức xác thực 1 request, dùng session và cookies.
- “Providers” cho biết cách thức truy vấn dữ liệu là eloquen hay query builder.
Mục tiêu
- Cài đặt được tiện ích xác thực đã có
- Mở rộng được tiện ích xác thực với các tùy chỉnh
5.1 AUTHENTICATION
Mặc định, Laravel đã tạo lớp Eloquent model App\User tại thư mục app, model này mặc định sử dụng Eloquent. Table users tương ứng để lưu trữ thông tin đăng nhập của user được lưu trữ tại database migrations, cài đặt dữ liệu mẫu tại thư mục seeds.
Laravel đã cung cấp vài lớp phục vụ cho xác thực tại namespace App\Http\Controllers\Auth
RegisterController quản lý người dùng đăng ký mới
LoginController quản lý người dùng đăng nhập
ForgotPasswordController quản lý người dùng phục hồi mật khẩu qua email
ResetPasswordController quản lý quên mật khẩu
Laravel cung cấp một cách tiếp cận nhanh chóng khi tạo các routes và views cần thiết khi phát triển ứng dụng có sử dụng phân quyền. Cú pháp thực hiện như sau:
Chú ý rằng, với câu lệnh trên chỉ phù hợp khi ứng dụng mới được phát triển. Câu lệnh trên sẽ tạo ra các trang đăng ký, đăng nhập, và các routes liên quan đến xác thực. Một controller HomeController cũng sẽ được tạo ra để quản lý vấn đề đăng nhập.
Các trang sẽ được lưu trữ tại thư mục resources\views\auth. Mặc định Bootstrap CSS framework đang được sử dụng, tuy nhiên việc này có thể tùy biến lại được.
Một số hiện thực đã được cung cấp được mô tả như bảng dưới đây: php artisan make:auth
STT Phương thức Mô tả
1 Auth::user() Lấy thông tin người dùng đã đăng nhập
2 Auth::id() Lấy thông tin id người dùng đã đăng nhập
3 Auth::guard(‘guard- name’)
Tùy chỉnh thông tin, cách thức xác thực
4 Auth::check() Kiểm tra xem người dùng hiện tại có được xác thực chưa
5 Auth::attempt([‘email’ => $email, ‘password’ => $password])
Kiểm tra thơng tin đăng nhập có tồn tại hay khơng
6 Auth::logout() Logout khỏi hệ thống
5.2 AUTHORIZATION
Tương tự như xác thực (authentication), phân quyền (authorization) cung cấp giải pháp tiếp cận khá đơn giản. Có 2 cách chính để tiến hành phân quyền trong Laravel gồm: gates và policies.
Gates và policies tựa như routes và controller trong Laravel. Gates cho biết nếu 1 user đã được phân quyền, được mô tả trong lớp App\Providers\AuthServiceProvider (sử dụng Gate facade)
Ví dụ trên minh họa cách thức đăng ký phân quyền, ngồi ra cịn có cách thức đăng ký khác
Có thể đăng ký nhiều Gate với các phương thức khác nhau (GET, POST, DELETE, …) public function boot()
{
$this->registerPolicies();
Gate::define('update-post', 'PostPolicy@update'); }
public function boot() {
$this->registerPolicies();
Gate::define('update-post', function ($user, $post) { return $user->id == $post->user_id;
}); } Gate::define('posts.view', 'PostPolicy@view'); Gate::define('posts.create', 'PostPolicy@create'); Gate::define('posts.update', 'PostPolicy@update'); Gate::define('posts.delete', 'PostPolicy@delete');
Như vậy việc đăng ký đã được tiến hành, để sử dụng trong chương trình khi kiểm tra một user có quyền thực hiện một thao tác nào đó hay khơng.
Với 2 phương thức được cung cấp: allows và denies, giúp cho việc xử lý với quyền hạn tương ứng của user.
Với Policies là những lớp được cung cấp để phân quyền xử lý nghiệp vụ trên một model hay resource cụ thể nào đó. Ví dụ như trong ứng dụng có blog, module tương ứng sẽ là Post, thì chính sách tương ứng với model sẽ là PostPolicy để phân quyền thao tác user trên model Post này.
Sử dụng php artisan với cú pháp như hình trên để tạo một polices.
Để đăng ký một polices được khai báo tại AuthServiceProvider if (Gate::allows('update-post', $post)) {
// The current user can update the post... }
if (Gate::denies('update-post', $post)) {
// The current user can't update the post... }
class AuthServiceProvider extends ServiceProvider {
public function boot() {
$this->registerPolicies(); //
Việc hiện thực các phương thức của polices dựa hoàn toàn các phương thức đã được khai báo trong model.
5.3 BÀI TẬP
Bài 1: Cài đặt và mở rộng tiện ích xác thực mà Laravel đã cung cấp
a) Cài đặt ứng dụng xác thực với 2 câu lệnh trên để chạy được ứng dụng
b) Mặc định dùng email để đăng nhập, hãy mở rộng ứng dụng để có thể đăng nhập bằng username hoặc email đều được
Bài 2: Tiếp tục phát triển từ bài 1
a) Định nghĩa 3 quyền: admin, user, guest
Admin: có tồn quyền trong hệ thống
User: chỉ có thể chỉnh sửa thơng tin của chính mình, khơng có quyền xem danh sách user, có quyền xem profile user
Guest: chỉ có quyền xem profile user b) Hiện thực tính năng với 3 quyền trên
php artisan make:auth php artisan migrate