Với vai trò là Developer, chúng ta hẳn đã rất quen với những form search dữ
liệu. Cụ thể là trong các màn hình Admin cần xem và lọc dữ liệu để dễ dàng cho việc quản lý.
Giải pháp có thể là tạo 1 controller, 1 action, trả ra 1 view. Khi nhập dữ liệu vào form search thì
sẽ submit lên chính controller đó, xử lý input và query để lấy dữ liệu tương ứng. Ta sẽ thực hiện
HTTP GET Request đưa các tham số lên URL. Tuy nhiên, nếu xử lí theo cách truyền thống thì
đến 1 lúc nào đó method xử lí sẽ bị “phồng” lên một cách nhanh chóng, và khó bảo trì trong
trường hợp xuất hiện nhiều QueryString trên URL. Vì thế chúng ta cần giải pháp khác để xử lí
bài toán ở trên, theo 1 cách khác dễ bảo trì và mở rộng nếu cần thiết.
6 trang |
Chia sẻ: Thục Anh | Ngày: 12/05/2022 | Lượt xem: 424 | Lượt tải: 0
Nội dung tài liệu Bộ lọc Querystring chuyên dụng và tác dụng trong việc bảo trì, mở rộng hệ thống, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
87
BỘ LỌC QUERYSTRING CHUYÊN DỤNG VÀ TÁC DỤNG
TRONG VIỆC BẢO TRÌ, MỞ RỘNG HỆ THỐNG
Nguyễn Thùy Linh
Hanoi University
Tóm tắt: Với vai trò là Developer, chúng ta hẳn đã rất quen với những form search dữ
liệu. Cụ thể là trong các màn hình Admin cần xem và lọc dữ liệu để dễ dàng cho việc quản lý.
Giải pháp có thể là tạo 1 controller, 1 action, trả ra 1 view. Khi nhập dữ liệu vào form search thì
sẽ submit lên chính controller đó, xử lý input và query để lấy dữ liệu tương ứng. Ta sẽ thực hiện
HTTP GET Request đưa các tham số lên URL. Tuy nhiên, nếu xử lí theo cách truyền thống thì
đến 1 lúc nào đó method xử lí sẽ bị “phồng” lên một cách nhanh chóng, và khó bảo trì trong
trường hợp xuất hiện nhiều QueryString trên URL. Vì thế chúng ta cần giải pháp khác để xử lí
bài toán ở trên, theo 1 cách khác dễ bảo trì và mở rộng nếu cần thiết.
Từ khóa: Controller, thread, channel
I. ĐẶT VẤN ĐỀ
Bài toán đưa ra: Cho phép admin xem các chủ đề (threads) trên diễn đàn (forum)
của mình, và cho phép admin lọc các threads dựa theo kênh (channel), các thông tin sẽ
được truy cập như sau: Tôi cần một màn hình Admin để xem danh sách các threads của
forum, các thread có các thông tin như user_id, channel_id. Tôi có thể lọc danh sách đó
theo các tiêu chí như theo user_id, channel_id hay sort theo popular giảm dần (popular
để đơn giản thì sẽ sắp xếp theo số lượng replies_count, nếu popular = 1 thì sắp xếp theo
replies_count giảm dần, nếu không tồn tại trên URL thì sẽ không sắp xếp.
Bài toán đưa ra khá đơn giản. Giải pháp có thể là tạo 1 controller, 1 action, trả ra 1
view. Khi nhập dữ liệu vào form search thì sẽ submit lên chính controller đó, xử lý
input và query để lấy dữ liệu tương ứng. Ta sẽ thực hiện HTTP GET Request đưa các
tham số lên URL.
Format URL ví dụ sẽ như sau: /threads?by=camnh&channel-id=1&popular=1
Ý nghĩa URL như sau: Lọc danh sách các threads được viết bởi “camnh”, với
channel_id=1 và popular giảm dần
Figure 1: ER model
88
Nếu xử lí bài toán theo cách truyền thống thì code sẽ được viết như sau:
Figure 2: Xử lí QueryString theo cách truyền thống
Chú ý với replies_count dòng 44 ở hình trên sẽ xử lí như sau
Figure 3: Add replies_count attribute to App\Thread model
Làm như thế này, replies_count attribute luôn đi kèm với Thread model khi
được gọi
Figure 4: Replies count attibutes được đính kèm với App\Thread model
89
Figure 5: Output expected
Nếu xử lí theo kiểu như Figure 2 thì đến 1 lúc nào đó thì method xử lí sẽ bị
“phồng” lên một cách nhanh chóng, và khó maintain trong trường hợp xuất hiện nhiều
QueryString trên URL. Vì thế chúng ta cần giải pháp khác để xử lí bài toán ở trên, theo
1 cách khác dễ bảo trì và mở rộng nếu cần thiết.
II. XỬ LÝ BÀI TOÁN
Để xử lí bài toán trên, chúng ta sẽ dùng “scope” trong Laravel, hướng xử lí như
sau:
Trong App\Thread model sẽ thêm 1 trait là Filterable, do một số Model không cần
chức
Figure 6: Xử lí bài toán theo hướng sử dụng Model scope
năng filter nên không cần thiết phải viết vào BaseModel rồi extends ra,, vì thế chọn
Trait là hợp lý. Ngoài ra, sẽ cần 1 attribute $filterable sẽ chỉ định class dùng để filter.
Mục đích của class này chỉ dùng để filter Threads dựa theo QueryString trên URL.
90
Figure 7: Thêm trait Filterable và chỉ định class để xử lí filters
Trong trait Filterable có gì
Figure 8: Nội dung trong trait Filterable
Trong class ThreadFilter, được reference từ dòng 21 trong Figure 8, do việc setup
__construct() giữa nhiều class Filter là giống nhau, vì thế để tránh lặp lại, ThreadFilter
sẽ được extends từ abstract class BaseFilter
Hướng xử lí như sau, với URL: /threads?by=camnh&channel-id=1&popular=1
Ở bên trong controller action trên Figure 6 dòng 29: request()->query() sẽ cho kết
quả như sau
[
‘by’ => ‘camnh’,
‘channel-id’ => 1,
91
‘popular’ => 1 - có thể tuỳ chuyển sang ‘asc’, ‘desc’
]
Tương ứng trong ThreadFilter class sẽ có 3 method tương ứng với kết quả ở trên
lần lượt là by(‘camnh’), channelId(1) và popular(1), mỗi method sau khi xử lí xong sẽ
return Builder ($this->builder) nhằm cho phép chaining với các method như latest(),
orderBy() sau khi filter.
Figure 9: BaseFilter class.
Trong ThreadFilter class, chi tiết bao gồm:
Figure 10: ThreadFilter class
92
Kết quả thu được tương tự như ở trên Figure 5, tuy nhiên khi làm theo cách này
nếu có nhiều QueryString trên URL sẽ dễ dàng mở rộng hơn bằng cách viết method ứng
với QueryString trong ThreadFilter là xong.
Figure 31: Chaining nếu cần thiết
III. KẾT LUẬN
Cùng một vấn đề, mỗi cách giải quyết sẽ mang lại hiệu quả khác nhau. Theo cách
giải quyết lọc QueryString chuyên dụng được giới thiệu trong nghiên cứu này, kết quả
thu được là tương tự, tuy nhiên trong trường hợp hệ thống có nhiều QueryString trên
URL thì việc bảo trì, mở rộng sẽ trở nên đơn giản hơn.
TÀI LIỆU THAM KHẢO
[1] Tungnguyen (2016). Laravel Eloquent Technique: Dedicated Query String
Filtering, available at URL https://viblo.asia/p/laravel-eloquent-technique-dedicated-
query-string-filtering-oZVRg4XZMmg5
[2]Vegibit (2020). How To Filter Via Query Strings, available at URL
https://vegibit.com/how-to-filter-via-query-strings/
Các file đính kèm theo tài liệu này:
- bo_loc_querystring_chuyen_dung_va_tac_dung_trong_viec_bao_tr.pdf