Một vài tính năng đơn giản trong Laravel mà không phải ai cũng biết.!
Bài đăng này đã không được cập nhật trong 4 năm
1. where n in 1
Ý là n where trong 1 where đó.
Giả sử bạn cần tìm danh sách các user trong bảng users
có first_name là Vu và có tuổi là 25.
select * from `users`
where `first_name` = 'DepTrai'
and `age` = 25;
OK, thường thì mình sẽ làm như sau.
User::where('first_name', 'DepTrai')
->where('age', 25)
->get();
Tuy nhiên chúng ta có thể sử dụng như sau:
User::whereFirstNameAndAge('DepTrai', 25)->get();
Nhìn có vẻ đẹp hơn đúng không các bạn. Thực chất thì viết như thế này chỉ để làm cho code nó đẹp hơn (theo ý cá nhân mình) thôi. Còn về query thì giống nhau. Trường hợp bạn muốn kết hợp thêm các điều kiện where với nhau thì các bạn chỉ việc truyền thêm vào câu query và các điều kiện tương ứng như sau.
User::whereCondition1AndCondition3AndCondition4('Condition1', 'Condition2', 'Condition3', 'Condition4')->get();
Nhớ rằng trong câu lệnh bắt đầu bằng where này, số lượng điều kiện đưa ra bên trái
sẽ phải không được vượt quá số lượng bên phải.
Nếu không nó sẽ báo lỗi Undefined offset: n.
2. Tìm kiếm nhiều kết quả với method find/findOrFail
Thông thường, chúng ta chỉ thường sử dụng find
, findOrFail
với mục đích là tìm kiếm một bản ghi duy nhất theo primary key
.
Thực chất thì chúng ta có thể tìm kiếm với nhiều bản ghi cũng được. Sử dụng bằng thay vì truyền vào một phần tử thì ta sẽ truyền vào mới một array.
$user = User::find(1); //ok
$users = User::find([1, 2, 3]) // okay.!
$user = User::findOrFail(1); //ok
$users = User::findOrFail([1, 2, 3]) // That's okay.! =))
Bởi tất cả chúng đều gọi đến method findMany
:
public function findMany($ids, $columns = ['*'])
{
$ids = $ids instanceof Arrayable ? $ids->toArray() : $ids;
if (empty($ids)) {
return $this->model->newCollection();
}
return $this->whereKey($ids)->get($columns);
}
Ngoài ra thì với find/findOrFail
, bạn có thể select các column mà bạn muốn lấy.
Xem đầy đủ tại đây.
3. Lựa chọn và sử dụng thông minh pagination
Mình cá là khá nhiều bạn đọc trên docs của Laravel mà không hề để ý đến phần này.
Với những cơ sở dữ liệu lớn có nhiều bản ghi, việc sử dụng paginate
thông thường sẽ không phải là một ý tưởng tốt vì nó sẽ query đếm tổng số tất cả bản ghi trên table sau đó sẽ phải tính toán tổng số page.
Thay vào đó bạn nên sử dụng simplePaginate
. ở đây thay vì việc bạn cần hiển thị các tất cả các page thì chúng ta sẽ ưu tiên bằng cách chỉ hiện thị các previous link
và next link
mà thôi.
So sánh thử sẽ có sự khác biệt:
// normal pagination
\App\Models\User::paginate(15);
// select count(*) as aggregate from `users`
// select * from `users` limit 15 offset 0
LengthAwarePaginator {#399 ▼
#total: 101
#lastPage: 7
#items: Collection {#439 ▶}
#perPage: 15
#currentPage: 1
#path: "http://localhost:8000"
#query: []
#fragment: null
#pageName: "page"
+onEachSide: 3
#options: array:2 [▶]
}
// simple pagination
// select * from `users` limit 16 offset 0
\App\Models\User::paginate(15);
Paginator {#254 ▼
#hasMore: true
#items: Collection {#253 ▶}
#perPage: 15
#currentPage: 1
#path: "http://localhost:8000"
#query: []
#fragment: null
#pageName: "page"
+onEachSide: 3
#options: array:2 [▶]
}
Một phần đáng chú ý nữa là mặc định, Laravel sẽ hiển thị số lượng link ở phần phân trang là 3 ( chính là phần onEachSide ). Tuy nhiên bạn có thể custom bằng cách thêm link hiển thị hoặc ít hơn bằng method onEachSide(number)
.
Xem chi tiết tại đây
4. Một chút về Eloquent Model
Trong class Model, có rất nhiều các properties được thiết lập sẵn, trong đó có $perPage
, thuộc tính này dùng để set mặc định số lượng bản ghi lấy ra theo mỗi page khi bạn sử dụng với Eloquent's pagination
.
protected $perPage = 10; // 10 rows/page
$appends
, bạn dùng nó khi cần lấy thêm thuộc tính này vào mỗi record sau khi lấy ra từ DB.
protected $appends = ['full_name'];
public function getFullNameAttribute()
{
return $this->first_name . ' ' . $this->last_name;
}
$touches
: Update lại thời gianupdated_at
của relationship. Giả sử bạn có một bài post có relation đến nhiềucomment
. Khi bạn xóa một comment, thì lập tức trườngupdated_at
của bài post cũng sẽ bị thay đổi theo thời gian comment bị xóa.- Sử dụng
replicate()
để clone một instance model:
$post = App\Models\Post::find(1);
$postClone = $post->replicate();
- Sử dụng method
is
để check duplicate:
$user = App\Models\User::find(1);
$post = App\Models\Post::find(1);
if ($user->is($post->user)) {
//
}
- Sử dụng
isDirty
để check sự thay đổi của các thuộc tính. Mình thường sử dụng trong Observer.
$post = App\Models\Post::find(1);
$post->title = 'Dep Trai';
if ($post->isDirty()) {
//
}
//hoặc
if ($post->isDirty('title') {
$question->last_edited_at = $question->updated_at;
}
- Sử dụng
increment
/decrement
để tăng giảm đơn vị của attribute.
$post->increment('post_view'); //default 1
$post->decrement('post_view', 3);
5. Sử dụng helper function
Ở đây mình giới thiệu một số hàm cần thiết và nên sử dụng nhé.
optional
: nhiệm vụ của nó là cho phép truy cập vào các attribute và method của đối tượng. Nếu không tồn tại attribute và method yêu cầu, nó sẽ mặc định trả về null. Sử dụng khi mà bạn chưa biết chắc chắn nó sẽ có attribute hay method cần tìm không.
$a = null;
$b = new Model();
optional($a)->doSomething(); // null
optional($a)->someProperty; // null
optional($b)->doSomething(); // calls doSomething on the Model object
optional($b)->someProperty; // the someProperty on the model object (if it exists)
abort
: Ném ra status code và message trả về đính kém. Ví dụ.abort(403);
,abort(404, 'Not Found')
;now
: Dùng hàm này thay choCarbon
. Bạn không cần useCarbon
nữa.now()
tương ứng vớiCarbon::now()
;tap
: Hàm này có 2 tham số, đầu tiên là value, thứ 2 là closure. Closure này thực hiện với giá trị truyền vào chính là tham số đầu tiên. Và method này trả về cái giá trị là kết quả của cái Closure kia. Ví dụ trong methodcreate
củaIlluminate\Database\Eloquent\Builder.php
:
return tap($this->newModelInstance($attributes), function ($instance) {
$instance->save();
});
tương ứng với
$instance = $this->newModelInstance($attributes)->save();
return $instance;
Dễ hơn rồi nhỉ . Hàm này mình dùng thường khi muốn viết code clean hơn.Cơ mà mình thấy thích hàm này nên cho vào luôn.
logger
&info
: Ngoài việc tự động lưulogs
trong quá trình phát triển dự án, bạn cũng có thể debug bằng cách sử dụnglogger
hoặcinfo
, chúng tương tự với việc sử dụngIlluminate\Log\Logger::debug($message)
hayIlluminate\Log\Logger::info($message)
. Thú thật là lúc trước mình toàn debug bằng cáchdd
vớidump
, có biết cái này đâu =)) giờ kể ra biết cũng tiện lợi phết. Nội dung của message sẽ được lưu vàostorage_path/logs/laravel-*.log
6. Sử dụng artisan down để đưa application của bạn vào chế độ Maintenance mode (503)
Đôi lúc bạn cũng muốn đưa app của mình về chế độ Maintenance mode. Để làm điều này Laravel cũng hỗ trợ cho chúng ta rồi.
php artisan down
Hoặc cũng có thể thêm option message để hiện thông báo:
php artisan down --message="Hello, 503"
Sau khi down rồi mà bạn muốn up thì chạy php artisan up
.
All rights reserved