Hướng dẫn dùng assighnment trong PHP

Xin chào các bạn, trong những bài viết trước mình đã chia sẻ với các bạn về Migration và Seeder trong Laravel - nó là các công việc cần thiết khi làm việc với DB, giúp cho việc tạo bảng, quản lý phiên bản, chèn dữ liệu một cách thuận tiện nhất. Như vậy sau những bước migration và seeding, thì chúng ta đã có một cơ sở dữ liệu với đầy đủ các bảng và dữ liệu trong bảng đó. Trở lại với bài viết mình muốn chia sẻ trong series Laravel và những điều thú vị thì hôm nay mình sẽ chia sẻ cho các bạn cách truy vấn và xử lý dữ liệu đang có trong cơ sở dữ liệu. Trước hết chúng ta sẽ tìm hiểu qua mô hình MVC là gì nhé.

1. Mô hình MVC

Chắc hẳn ai bắt đầu với sự nghiệp làm web cũng không thể không biết mô hình MVC. Mình sẽ nói sơ lược lại một chút nhé. MVC(Model- View- Controller) là mô hình phân chia application thành 3 thành phần chính và mỗi thành phần lại có nhiệm vụ riêng của nó:

  • Model: chứa các logic nghiệp vụ và thao tác với DB.
  • View: thực hiện công việc hiển thị và tương tác với người dùng.
  • Controller: làm nhiệm vụ điều hướng giữa các đối tượng tham gia hệ thống. Ví dụ như người dùng có một request lên thì route định tuyến vào controller, thì controller sẽ điều hướng đến cho một Model tương ứng xử lý sau đó kết quả trả về cho Controller , Controller sẽ chuyển đến dữ liệu cho View.
    Hướng dẫn dùng assighnment trong PHP

Ví dụ

Lý thuyết trên khó hiểu ghia, mình sẽ lấy một ví dụ để các bạn dễ hiểu hơn nhé. Chắc hẳn các bạn hay đi uống trà sữa đúng không nào

Hướng dẫn dùng assighnment trong PHP
))) Một ngày đẹp trời mình đi đến 157 Xã Đàn để uống Lee Tee, khi vào quán thì mình sẽ order đồ uống. Mình là người dùng, và trà sữa Ô Long Kem Cheese Size L full topping là yêu cầu của người dùng
Hướng dẫn dùng assighnment trong PHP
))). Nhân viên order vui vẻ tươi vui gật đầu(giả sử quán lúc đó có một nhân viên làm việc vừa order vừa pha chế luôn cho khách). Với bạn nhân viên order, trà sữa là cần làm theo qui trình các bước:

  • Lấy cốc
  • Gián tem tên đò uống
  • Pha trà sữa
  • Cho topping
  • Đổ lớp kem cheese lên bề mặt
  • Đóng hộp
  • Đưa đồ cho khách

Não của nhân viên bán trà sữa đong vai trò là controller. Ngay khi mình đến order trà sữa thì nhân viên bán trà sữa đã hiểu và bắt đầu công việc. Pha trà sữa bản chất cũng giống như giống như pha các loại nước bình thường, có điều nguyên liệu và công cụ hoàn toàn khác nhau. Bạn nhân viên bán hàng có thể sử dụng công cụ của cửa hàng. Những công cụ đó đóng vai trò là Model bao gồm:

  • Đôi tay bạn nhân viên
  • Nguyên liệu để pha trà sữa
  • Máy pha trà
  • Đá lạnh
  • Máy đóng hộp
  • Đường, topping, chân trâu,...

Cuối cùng cốc trà sữa sau khi đóng hộp mà mình cầm trên tay đóng vai trò là View được làm nên từ các công cụ trong phần Model, chế biến và giao đồ thông qua phần Controller(não của bạn nhân viên).

2. Eloquent Model

ORM(Object Relational Mapping) đây là tên gọi chỉ việc ánh xạ các record dữ liệu trong hệ quản trị cơ sở dữ liệu sang dạng đối tượng mà mã nguồn đang định dạng trong class. Eloquent ORM: Larvel đã sử dụng kỹ thuật ORM giúp lập trình viên thao tác dễ dàng hơn với DB. Trong phần này chúng ta sẽ nói nhiều đến phần kiến thức

protected $connection = 'connection-name';
6 (Model) - là một phần trong mô hình MVC ở trên. Các Model này sẽ thao tác trực tiếp với DB, xử lý logic nghiệp vụ và trả về dữ liệu cho controller.

Định nghĩa Model và các thiết lập cơ bản

Chúng ta sẽ định nghĩa ra model bằng câu lệnh

protected $connection = 'connection-name';
7 trong command Artisan.

php artisan make:model Post

Sau khi nhấn lệnh thì trong app/Post.php sẽ sinh ra đoạn code sau:



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

Để tạo model và migration chúng ta sẽ thêm option

protected $connection = 'connection-name';
8 hoặc
protected $connection = 'connection-name';
9

php artisan make:model Post --migration
php artisan make:model Post -m

Các bạn chú ý tên model để mapping cho đúng với bảng trong CSDL. Nếu table trong CSDL là



use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
0 thì tên model đặt đúng theo chuẩn là


use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
1.

Tên bảng

Mặc định nếu như bạn đặt tên model là



use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
1 thì laravel sẽ mapping với bảng tên


use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
0. Những nếu bạn muốn đặt tên bảng khác đi nhưng vẫn phải theo đúng quy chuẩn convention đặt tên trong Laravel nhé(snake case). Ví dụ mình không đặt tên


use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
0 nữa mà mình đặt tên là


use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
5 chẳng hạn thì biến


use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
6 trong


use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
7 sẽ mapping đúng model với tên bảng chúng ta khai báo.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_posts';
}

Khóa chính của bảng

Theo mặc định trong Laravel thì khóa chính của mỗi bảng sẽ là



use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
8. Nhưng đôi lúc chúng ta muốn thay đổi trường khóa chính này với tên khác như là


use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
9 thì chúng ta có thể khai báo qua biến


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

00.

protected $primaryKey = 'id_post';

Các bạn chú ý nhé, kiểu dữ liệu của khóa chính là



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

01 và nếu các bạn không muốn khóa chính của bạn tự tăng thì


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

02. Nếu kiểu dữ liệu của khóa chính không phải là kiểu


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

01 thì bạn nên set biến


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

04.

Timestamps

Mặc định khi các bạn tạo bảng thì sẽ có 2 trường



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

05 và


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

06, những khi bạn thêm các bản ghi vào table thì 2 trường này sẽ tự động cập nhật cho nó. để eloquent không tự cập nhật giá trị cho 2 trường này mỗi khi bạn thêm record thì chúng ta sẽ set trong model như sau:

public $timestamps = false;

Nếu bạn không muốn lưu dữ liệu của timestamp như mặc định của nó bạn có thể thay đổi định dạng của nó trong model như sau:

protected $dateFormat = 'd-m-Y';

Và nếu bạn muốn custom lại tên cột của



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

07, bạn cần set trong model như sau:

const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_update';

Kết nối DB

Tất cả các Eloquent models sẽ sử dụng DB mặc định khai báo trong file .env, nhưng nếu bạn muốn model này kết nối tới một bảng trong CSDL nào đó thì chúng ta sẽ set như sau trong model:

protected $connection = 'connection-name';

Chú ý

Để chác chắn là model của chúng ta mapping đúng với table trong CSDL hay chưa thì chúng ta sẽ test bằng



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

08. Ví dụ bảng posts có các trường (id, title, content, created_at, updated_at)

Hướng dẫn dùng assighnment trong PHP
Nếu trả về


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

09 thì chứng tỏ Eloquent đã mapping đúng model với table trong CSDL rồi.

Lấy dữ liệu từ DB

all

Khi chúng ta đã thiết lập những tham số như trên xong, thì chúng ta bắt tay vào lấy dữ liệu từ DB về. Để lấy tất cả các bản ghi trong 1 table chúng ta dùng



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

10:



use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }

Thêm rằng buộc cho câu truy vấn

Có những trường hợp mà chúng ta không cần thiết lấy tất cả các record của table ra, nó làm hiệu năng chương trình của chúng ta kém. Nên thêm những rằng buộc cho câu truy vấn là rất quan trọng để giảm bớt query không cần thiết và tăng hiệu năng chương trình.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

0

Collections

Vì các hàm của Eloquent như



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

11 và


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

12 đều trả về nhiều kết quả, hay đó là một instance từ


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

13 sẽ được trả về. Class


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

14 cũng cấp các hàm hữu ích để làm việc với các kết quả Eloquent trả về. Các bạn có thể tham khảo các collection ở đây. Mình sẽ lấy một ví dụ về cách sử dụng collections nhé.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

1

Chunk

Nếu bạn muỗn xử lý hàng ngán kết quả từ Eloquent, sử dụng



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

15 sẽ tiết kiệm được memory khi thao tác với tập dữ liệu kết quả lớn. hàm này sẽ lấy từng


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

15 của Eloquent models, cung cấp chúng thông qua


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

17 để xử lý.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

2

Cursors

Hàm



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

18 cho phép bạn duyetj qua records bằng cách sử dụng một cursor(con trỏ), nó chỉ thực thi cho một truy vấn. Khi dữ liệu lớn, hàm


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

18 có thể được sử dụng để giảm memory sử dụng.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

3

Lấy dữ liệu một Model/Aggregates

Ngoài việc lấy tất cả các records của table bằng hàm



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

10, chúng ta có thể lấy model instance bằng hàm


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

21 hoặc


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

22



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

4

NotFound Exception

Nhưng có lúc mà bạn muốn bắn ra một exception nếu instance model không tìm thấy. Hàm



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

23 và


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

24 sẽ trả kết quả đầu tiên của query, tuy nhiên nếu không có kết quả, thì


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

25 sẽ được bắn ra cho người dùng. Chúng ta nên đặt trong


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

26.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

5

Nếu exception mà không được bắt thì một HTTP response 404 sẽ tự động được gửi lại cho user.

Aggregates

bạn cũng có thể sử dụng các



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

27 như


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

28.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

6

Insert và Update Models

Insert

Để tạo một bản ghi mới trong table, thì chúng ta sẽ tạo một model instance, sau đó chúng ta set giá trị của thuộc tính, sau đó dùng phương thức



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

29.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

7

Trong ví dụ trên chúng ta không tạo 2 trường



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

05 và


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

06 mà khi


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

29 sẽ tự động fill dữ liệu hai trường đó trong CSDL.

Updates

Hàm



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

29 cũng được dùng để cập nhật model đã tồn tại trong database, dầu tiên bạn cần lấy model instance ra trước, bạn thay đổi các thuốc tính trong model instance, rồi gọi hàm


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

29. Giá trị hàm


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

06 sẽ tự động được cập nhật, bạn không cần thay đổi thủ công giá trị này.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

8

Mass Updates

Nhiều khi chúng ta cần update nhiều bản ghi một lúc thì chúng ta sẽ làm sau đây. Ví dụ như tất cả các các bài post chưa pulish thì sẽ được pulish hết.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

9

Hàm



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

36 sẽ nhận một mảng


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

37, với key chính là tên trường cần update và value chính là giá trị update.

Mass Assignment



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

38 là tính năng cho phép lập trình một cách tự đọng gán các tham số của một HTTP request vào các biến hoặc đối tượng trong lập trình.Ví dụ chúng ta có một form đang ký sản phẩm của người dùng như sau:

php artisan make:model Post --migration
php artisan make:model Post -m
0

Sau kh i submit form dữ liệu lên chúng ta có thể ghi dữ liệu này vào CSDL bằng đoạn code như sau(ta bỏ qua vấn đề validate dữ liệu nhập vào):

php artisan make:model Post --migration
php artisan make:model Post -m
1

Thật ngắn gọn và đơn giản đúng không các bạn, tính năng này gọi là Mass Assignment. Tuy nhiên có một lỗ hổng bảo mật xảy ra nếu một người truy cập cố tính gửi dữ liệu



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

39 trong bảng users chẳng hạn để người đó có quyền là admin. Để xử lý lỗ hổng trong Mass Assignment, Laravel đưa ra thêm hai thuộc tính cho Model là


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

40 và


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

41. Ví dụ

php artisan make:model Post --migration
php artisan make:model Post -m
2



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

40 cho phép thiết lập các cột trong một bảng có thể sử dụng tính năng Mass Assignment, khi đó ta có thể thực hiện

php artisan make:model Post --migration
php artisan make:model Post -m
3

Khi đó kẻ muốn phá hệ thống của chúng ta khổng thể gửi thêm input



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

43 là trường không có trong


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

40. Như vậy lỗ hổng trong Mass Assignment đã được Laravel đã được xử lý. Trái ngược lại với


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

40 là


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

41. Chú ý rằng chúng ta không khai báo cả hai thuộc tính nãy đồng thời lần nhau. Và một vấn đề là


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

40 và


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

48 chỉ có tác dụng với các phương thức của Eloquent Model, với các phương thức của Query Buider thì nó không có tác dụng.
Có hai phương thức tạo bản ghi mới sử dụng Mass Assignment khác là


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

49 và


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

50. Như ngay tên phương thức thì các bạn cũng đoán ra chức năng của từng phương thức.

  • 
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
        //
    }
    
    
    49: sẽ tìm các bản ghi sử dụng cặp cột và giá trị, nếu không tìm thấy, một bản ghi sẽ được tạo ra với các thuộc tính này.
  • 
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
        //
    }
    
    
    50: nó không ghi vào CSDL mà trả về một instance của model, chỉ ghi dữ liệu vào CSDL sau khi gọi phương thức
    
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Post extends Model
    {
        //
    }
    
    
    29.
php artisan make:model Post --migration
php artisan make:model Post -m
4

Một phương thức nữa cũng rất hay dùng đó là :



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

54

php artisan make:model Post --migration
php artisan make:model Post -m
5

Deleting Model

Để xóa bản ghi dữ liệu đơn gainr bằng cách chúng ta gọi đến phương thức



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

55

php artisan make:model Post --migration
php artisan make:model Post -m
6

Soft Deleting

Bây giờ bài toán đặt ra là khi chúng ta lỡ tay đã xóa bản ghi khỏi table, bây giờ chúng ta muốn lấy lại nó(khoc). Nhưng không sao, Laravel có cơ chế hỗ trợ người dùng khi lỡ tay xóa một bản ghi có thể lấy lại được đó chính là soft delete (xóa mềm). Tức là tưởng xóa những thực chất không xóa

Hướng dẫn dùng assighnment trong PHP
. Thực chất là chúng ta chỉ thêm một trường


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

56 để đánh dấu bản ghi này đã được xóa. Để cho phép một Model có thể thực hiện được đánh dấu bản ghi đã xóa, chúng ta sử dụng trait


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

57 và thêm


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

56 vào thược tính


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

59 của nó.

php artisan make:model Post --migration
php artisan make:model Post -m
7

Trong file migration tạo bảng



use App\Post;

$flights = App\Post::all();

foreach ($posts as $post) {
    echo $post->title. "
"
; }
0 bạn nhớ thêm


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

61. Khi đó, nếu bạn thực hiện phương thức


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

55 thay vì nó sẽ xóa triệt để trong CSDL thì nó sẽ cập nhật thời gian hiện tại vào trường


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

56, và như vậy bản ghi này coi như là đã xóa khỏi table. Để xem xem bản ghi này đã được đánh dấu là xóa tạm thời hay chưa các bạn sử dụng phương thức


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

64.

php artisan make:model Post --migration
php artisan make:model Post -m
8

Để truy vấn những bản ghi đã xóa thì chúng ta sử dụng



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

65

php artisan make:model Post --migration
php artisan make:model Post -m
9

Ngược lại nếu bạn muốn truy vấn kết quả từ những bản ghi mà đã xóa mêm thì bạn sử dụng phương thức



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

66.

Đôi lúc bạn sẽ muốn tất cả các bạn ghi đã xóa mềm rồi quay lại như trước. sử dụng phương thức



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

67.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_posts';
}
0

Chú ý, để xóa vĩnh viễn bản ghi dùng phương thức



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

68.

Query Scope

Vấn đề đặt ra là, nhiều khi một rằng buộc nào đó được sử dụng rất nhiều trong các câu truy vấn ở nhiều controller. Vì thế



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

69 sinh ra để giải quyết vấn đề này. Có 2 loại Scope:


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

70 và


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

71.

Global Scope

Với phạm vi biến cục thì định nghĩa scope này sẽ áp dụng cho một Model và những truy vấn liên quan đến nó sẽ được áp dụng thêm rằng buộc. Sau đây mình sẽ lấy một ví dụ cho các bạn xem cách khai báo



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

72 như thế nào nhé. Đầu tiên ta sẽ tạo thư mục app/Scopes và tạo file PriceScope.php.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_posts';
}
1

Để đăng ký global scope thì chúng ta sẽ override lại phương thức



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

73 trong Model.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_posts';
}
2

Và khi ta sử dụng truy vấn



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

74 thì chỉ những product nào có price > 200000 mới được lấy ra. Ngoài ra các bạn còn có thể định nghĩa global scope bằng Closure.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_posts';
}
3

Nếu bạn muốn truy cập mà không bị ảnh hưởng nào từ global scope thì chúng ta có thể sử dụng phương thức



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

75. Nếu ta không truyền tham số nào vào trong phương thức này thì mặc định Laravel sẽ tự hiểu là bỏ hết tất cả các global scope đi.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_posts';
}
4

Local Scope



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

76 định nghĩa ra để phục vụ cho chính Model đó thôi. Các bạn hãy xem ví dụ nhé.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_posts';
}
5

Khi các bạn dùng chỉ cần gọi đến



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

77 là nó sẽ tự hiểu.



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_posts';
}
6

Events

Eloquent bắn ra một số các events: creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored. Các bạn có thể tìm thấy trong



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

78 có sử dụng


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

79 trong đó hàm


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

80 chứa rất nhiều các events mà Eloquent sẽ bắn ra:



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'my_posts';
}
7

Sử dụng các events của Eloquent này rất tiện dụng, ví dụ như khi bạn tạo ra một chương trình quảng cáo, thi sau khi bạn



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

29 thì events


namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

82 có thể bắn ra notification cho người dùng biết là có một chương trình quảng cáo mới.

Observers

Nếu chúng ta cần listen nhiều event trong model thì bạn cần tạo một



namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

83 - nơi chứa tất cả mọi lắng nghe từ event của Eloquent bắn ra.