- vừa được xem lúc

Scope trong Laravel.

0 0 22

Người đăng: quycoi

Theo Viblo Asia

Chào các bạn, ngày hôm này mình sẽ cùng các bạn tìm hiểu qua cách sử dụng scope cơ bản trong Laravel.

Global Scope

Hãy tưởng tượng rằng bạn cần thêm một ràng buộc vào tất cả các truy vấn tới model. Nếu các bạn đã từng tìm hiểu qua soft delete trong laravel thì nó chính là một dạng global scope, mỗi khi truy vấn tới model sẽ chỉ lấy ra các bản ghi chưa được xóa mềm từ database. Viết một global scope sẽ giúp chúng ta thuận tiện hơn khi thêm ràng buộc tới từng truy vấn tới model.

Writing Global Scopes

Đầu tiên chúng ta tạo một class implement interface Illuminate\Database\Eloquent\Scope . Interface Scope yêu cầu bạn phải có một phương thức apply. Sau đó chúng ta có thể thêm các mệnh đề where hoặc ràng buộc để giống như ví dụ dưới đây:

<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope; class AncientScope implements Scope
{ /** * Apply the scope to a given Eloquent query builder. * * @param \Illuminate\Database\Eloquent\Builder $builder * @param \Illuminate\Database\Eloquent\Model $model * @return void */ public function apply(Builder $builder, Model $model) { $builder->where('created_at', '<', now()->subYears(2000)); }
}

Applying Global Scopes

Để có thể thực hiện gán một global scope cho một model bạn cần phải ghi đè phương thức static booted của model và gọi phương thức addGlobalScope của model:

<?php namespace App\Models; use App\Scopes\AncientScope;
use Illuminate\Database\Eloquent\Model; class User extends Model
{ /** * The "booted" method of the model. * * @return void */ protected static function booted() { static::addGlobalScope(new AncientScope); }
}

Sau khi chúng ta đã thêm global scope như ví dụ trên, ghi truy vấn User::all() câu truy vấn bây giờ sẽ tương tự như sau:

select * from `users` where `created_at` < 0021-02-18 00:00:00

Anonymous Global Scopes

Eloquent cũng giúp chúng ta có thể thêm một global scope bằng closures, khi sử dụng closures để định nghĩa global scope bạn nên xác định tên global scope ở tham số đầu tiên như ví dụ dưới đây:

<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; class User extends Model
{ /** * The "booted" method of the model. * * @return void */ protected static function booted() { static::addGlobalScope('ancient', function (Builder $builder) { $builder->where('created_at', '<', now()->subYears(2000)); }); }
}

Removing Global Scopes

Đương nhiên cũng có nhiều trường hợp chúng ta không cần dùng đến global scope cho một truy vấn nào đó, Laravel đã giúp chúng ta tất cả mọi thử rồi bạn chỉ cần sử dụng phương thức withoutGlobalScope với tham số đầu tiên là tên class scope của bạn hoặc nếu bạn sử dụng closures để định nghĩa global scope bạn cần thêm vào tên của global scope đó:

//class scope
User::withoutGlobalScope(AncientScope::class)->get(); //closures scope
User::withoutGlobalScope('ancient')->get();

Nếu bạn muốn xóa tất cả ràng buộc global scope hoặc một vài cái thì bạn có thể sủ dụng phương thức withoutGlobalScopes

// Remove all of the global scopes...
User::withoutGlobalScopes()->get(); // Remove some of the global scopes...
User::withoutGlobalScopes([ FirstScope::class, SecondScope::class
])->get();

Local Scopes

Khác với global scope là luôn gọi đến ràng buộc mỗi khi truy vấn, local scope sẽ giúp bạn định nghĩa những trường hợp bạn cần thêm ràng buộc và gọi tới nó bất cứ đâu. Để định nghĩa một local scope bạn cần thêm một phương thức bắt đầu với scope trong model:

<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class User extends Model
{ /** * Scope a query to only include popular users. * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopePopular($query) { return $query->where('votes', '>', 100); } /** * Scope a query to only include active users. * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopeActive($query) { return $query->where('active', 1); }
}

Utilizing A Local Scope

Để sử dụng local scope cũng đơn giản thôi chúng ta chỉ cần gọi tới tên scope mỗi khi muốn truy vấn tới model ví dụ:

use App\Models\User; $users = User::popular()->active()->orderBy('created_at')->get();

Và bạn để ý rằng không có chứ scope phía trước mỗi khi gọi tới tên của local scope nhé.

Dynamic Scopes

Laravel cũng hỗ trợ chúng ta thêm tham số vào local scope mỗi khi chúng ta cần gọi đến ví dụ sau đây tôi sẽ truyền vào local scope một tham số type để thêm value cho ràng buộc của mình:

<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class User extends Model
{ /** * Scope a query to only include users of a given type. * * @param \Illuminate\Database\Eloquent\Builder $query * @param mixed $type * @return \Illuminate\Database\Eloquent\Builder */ public function scopeOfType($query, $type) { return $query->where('type', $type); }
}

Sau đó mỗi khi gọi tới tôi chỉ cần thêm giá trị tham số type vào scope

$users = User::ofType('admin')->get();

Dưới đây là một chút chia sẻ về scope trong Laravel. Cảm ơn các bạn đã quan tâm. Tham khảo: https://laravel.com/docs/8.x/eloquent#anonymous-global-scopes

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tìm hiểu về Resource Controller trong Laravel

Giới thiệu. Trong laravel, việc sử dụng các route post, get, group để gọi đến 1 action của Controller đã là quá quen đối với các bạn sử dụng framework này.

0 0 335

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 421

- vừa được xem lúc

Sử dụng Swagger để xây dựng API documentation

Giới thiệu về Swagger. RESTful API là một tiêu chuẩn dùng trong việc thiết kế API cho các ứng dụng web (thiết kế Web services) để tiện cho việc quản lý các resource.

0 0 1k

- vừa được xem lúc

Ví dụ CRUD với Laravel và Vuejs.

1. Cài đặt Laravel. composer create-project --prefer-dist laravel/laravel vuelaravelcrud. .

0 0 141

- vừa được xem lúc

Một số tips khi dùng laravel (Part 1)

1. Show database query in raw SQL format. DB::enableQueryLog(); // Bật tính năng query logging. DB::table('users')->get(); // Chạy truy vấn bạn muốn ghi log.

0 0 69

- vừa được xem lúc

Inertiajs - Xây dựng Single Page App không cần API

Tiêu đề là mình lấy từ trang chủ của https://inertiajs.com/ chứ không phải mình tự nghĩ ra đâu nhé :v. Lâu lâu rồi chưa động tới Laravel (dự án cuối cùng mình code là ở ver 5.8), thế nên một ngày đẹp trời lượn vào đọc docs ver 8.

0 0 227