[Laravel] Note 1: SQL & Helper in blade view file
Bài viết tổng hợp 1 số tips trong Laravel
1. Feature Toggle in laravel
Thêm helper cho blade, việc bật/tắt hiển thị giờ sẽ do config, dễ dàng hơn. Ví dụ chức năng login with Facebook
- Tạo file cấu hình (
config/features.php
)1
2
3
4
5
6
7
8
9
10
return [
'loginWithGoogle' => true,
'newSearchBox' => true,
'newsLetterBox' => false,
/*
Some Features ....
*/
]; - Sau đó chỉnh sửa file
AppServiceProvider
và thêm helper cho phương thứcboot()
1
2
3Blade::if('feature', function ($feature) {
return config("features.$feature", false);
}); - Done! Giờ bạn có thể dùng ở blade files (views)
1
2
3
4
5
6@feature('loginWithGoogle')
<a href="#" class="btn btn-primary-soft">
<i class="fa fa-google"></i>
<span>Login With Google</span>
</a>
@endfeature
3. Sáu cách để thực hiện 1 truy vấn SQL
3.1. Một số cách load dữ liệu trong quan hệ của Laravel
Trước khi xem các cách thực hiện truy vấn trong Larael, chúng ta cùng điểm qua xem Eloquent của Laravel sử dụng lấy dữ liệu như thế nào nhé.
Eloquent trong Laravel cung cấp cho chúng ta 3 cách query dữ liệu: Lazy load
, Eager Loading
, Lazy Eager Loading
Lazy load (chỉ lấy dữ liệu chính nó)
Đây là các lấy dữ liệumặc định, các Eloquent sẽ chỉ lấy các dữ liệu của chính nó mà không query để lấy các quan hệ1
2$users = User::all()
$flight = App\Flight::where('number', 'FR 900')->first();
Eager Loading (lấy parent model cùng các quan hệ)
Khi bạn thực hiện truy cập quan hệ Eloquent như thuộc tính, dữ liệu relationship đó là “lazy loaded”. Điều đó có nghĩa relationshop data không thực sự được load cho tới khi lần đầu bạn truy cập vào thuộc tính của nó. Tuy nhiên, Eloquent có thể “eager load” relationship tại thời điểm bạn truy vấn vào parent model. Eager loading giải quyết vấn đề N + 1 truy vấn1
$books = App\Book::with('author')->get();
Phương thức with
này sử dụng lấy quan hệ cho tất cả các books. Nếu muốn load quan hệ theo từng model, hãy xem xét phương thức load()
bên dưới. Điều đó có nghĩa là truy vấn sau sẽ không có ý nghĩa lấy User có id là 1 và quan hệ của nó:1
2$user = User::find(1)->with('posts')->get();
// find không có ý nghĩa vì nó load hết quan hệ và trả về tất cả users
Lazy Eager Loading (lấy parent model xong sau đó quyết định có lấy các quan hệ hay không vì mặc định nó chỉ lấy parent model chính là lazy loading)
Đôi khi bạn có thể cần eager load 1 quan hệ sau khi parent model được lấy. Ví dụ điều này cực kì hữu ích nếu bạn muốn quyết định có load các model liên quan trong quan hệ hay không?1
2
3
4
5$books = App\Book::all();
if ($someCondition) {
$books->load('author', 'publisher');
}
Trái với with
là lấy dữ liệu quan hệ toàn bộ các model, load
sẽ được sử dụng để lấy các quan hệ của 1 model do bạn chỉ định :D1
$posts = User::find(1)->load('posts'); // không dùng with nhé
Ngoài lề: Dynamic relationships in Laravel using subqueries
Ơ thì đằng nào cũng đang nói về quan hệ mình xin nói luôn 1 bài toán khá hay mình đã gặp. Thông thường các quan hệ được liên kết thông qua khóa ngoài, phép so sánh bằng, như user_id trong bảng posts bằng với id trong bảng users. Tuy nhiên đôi khi lại có 1 chút khác biệt, giả sử user_id trong bảng posts lại là giá trị id trong bảng user cộng thêm 1 thì sao (ví dụ thôi nhé, thực tế chắc không có). Hay một bài toán khác lấy lần login cuối cùng của 1 user, dữ liệu thực tế chúng ta muốn lấy chỉ là 1 bản ghi trong bảng logins chứ không phải toàn bộ dữ liệu logins của users rồi mới xử lý tiếp. Lúc đó hãy dùng subquery để xây dựng ra các quan hệ động nhé :D
Link bài viết gốc: https://reinink.ca/articles/dynamic-relationships-in-laravel-using-subqueries
3.2 Một số truy vấn trong Laravel
Chúng ta cùng xem xét 6 cách truy vấn DB trong Laravel
Given this tables:1
2
3
4
5
6
7
8Users
id
name
Posts
id
content
user_id
Select all post from specific user:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/* First Way */
$user = User::find(1); // Just Eloquent
$posts = $user->posts; // Just Eloquent
/* Second Way */
$posts = User::with('posts')->find(1); // Eloquent with Eager loading
/* Third Way */
$posts = User::find(1)->load('posts'); // Eloquent with Lazy Eager Loading
/* Fourth Way */
$posts = User::join('posts', 'users.id', '=', 'posts.user_id')
->where('users.id', 1)
->get();
// Eloquent with Query Builder methods
/* Fifth Way */
$posts = DB::table('users')
->join('posts', 'users.id', '=', 'posts.user_id')
->where('users.id', 1)->get();
// Just Query Builder
/* Sixth Way */
$posts = DB::select(
'select * from users join posts on users.id = posts.user_id where users.id = 1'
); // Just SQL
4. Xem SQL query được sinh ra bởi Eloquent hoặc Query Builder. Ghi log
Laravel cung cấp 1 số phương thức giúp bạn dump câu lệnh truy vấn toSql()
, getBindings()
1
2
3
4
5
6
7
8App\Models\Division::where('type', 'rx')->toSql();
// generates the following query:
"select * from `divisions` where `type` = ?"
$query = DB::table('table')->whereIn('some_field', [1,2,30]);
$bindings = $query->getBindings();
// Giá trị mảng truyền vào truy vấn
Vậy nếu để gộp 2 kết quả trên thành 1 truy vấn hoàn chỉnh thì sao nhỉ? Bạn chỉ cần thay các giá trị ?
từ phương thức toSql()
thành các giá trị nhận được từ phương thức getBindings()
:D1
2
3
4
5
6
7
8
9public function getQueries(Builder $builder)
{
$addSlashes = str_replace('?', "'?'", $builder->toSql());
return vsprintf(
str_replace('?', '%s', $addSlashes),
$builder->getBindings()
);
}
Chi tiết bạn có thể xem thêm tại đây
Phương thức dd()
hay dump()
cũng là 1 cách xem SQL Query:1
2
3DB::table('users')->where('votes', '>', 100)->dd();
DB::table('users')->where('votes', '>', 100)->dump();
Link: https://laravel.com/docs/7.x/queries#debugging
Để ghi các truy vấn vào log, hãy enableQueryLog lên rồi ghi vào log bình thường nhé :D1
2
3
4
5
6// Toàn bộ truy vấn sẽ được ghi lại từ khi enableQueryLog()
DB::enableQueryLog();
App\User::where(['id'=>'1'])->delete();
Log::info(DB::getQueryLog());
[Laravel] Note 1: SQL & Helper in blade view file
http://yoursite.com/2019/11/23/Laravel-Note-1-SQL-Helper-in-blade-view-file/