Conditional attributes và relationships trong Laravel Resources Chuyên mục PHP và Laravel 2023-07-27 345 Lượt xem 90 Lượt thích 0 Bình luận
Khi bạn đang xây dựng một ứng dụng Laravel sử dụng API tại một thời điểm nào đó, sẽ không có gì phải đắn đo khi sử dụng các resource classes của Laravel vì nó cung cấp lớp chuyển đổi nằm giữa các model Eloquent của bạn và các responses JSON thực sự được trả lại cho người dùng ứng dụng của bạn.
Trong bài viết này, tôi sẽ đặc biệt nói về các thuộc tính có điều kiện chỉ có thể được sử dụng chứa một thuộc tính trong resource response nếu một điều kiện nhất định được đáp ứng.
Vì vậy, như bạn có thể biết, mỗi resource response chứa một phương thức toArray sẽ dịch các thuộc tính của model của bạn thành một mảng thân thiện với API có thể được trả lại cho người dùng của bạn như bên dưới:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class Post extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
Bây giờ, nếu chúng ta chỉ muốn chứa một attribute trong một resource response nếu một điều kiện nhất định được đáp ứng, thì có các phương thức trợ giúp trong Laravel có thể được sử dụng để thực hiện thao tác này. Một trong số đó là phương thức when có thể được sử dụng để thêm thuộc tính vào resource response một cách có điều kiện. Vì vậy, hãy thay đổi ví dụ trên:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class Post extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'content' => $this->when($this->is_published === 1, $this->content),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
Trong ví dụ này, content chỉ được trả về trong resource response cuối cùng nếu bài post published. Nếu nó chưa được published, content sẽ bị xóa hoàn toàn khỏi resource response trước khi nó được gửi lại cho FE.
Phương thức when cho phép bạn xác định rõ ràng các resource response của mình mà không cần dùng đến các câu lệnh điều kiện khi xây dựng mảng.
Phương thức when cũng chấp nhận Closure làm đối số thứ hai của nó, cho phép bạn chỉ tính toán giá trị kết quả nếu điều kiện đã cho là đúng. Chẳng hạn, nếu bạn muốn thay đổi nội dung trước khi gửi cho FE, bạn có thể thực hiện như sau:
'content' => $this->when($this->is_published === 1, function () {
return htmlspecialchars($this->content)
})
Merging multiple attributes
Có một phương pháp mergeWhen có thể được sử dụng để chứa nhiều thuộc tính có điều kiện trong phản hồi tài nguyên. Đây là cách bạn có thể làm điều đó:
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
$this->mergeWhen($this->is_published === 1, [
'content' => $this->content,
'tags' => $this->tags
]),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
Như bạn có thể thấy mergeWhen tương tự như when, ngoại trừ việc bạn có thể cung cấp nhiều thuộc tính có điều kiện dưới dạng một mảng trong đối số thứ hai của phương thức. Nếu điều kiện đã cho là sai, cả hai thuộc tính trên sẽ không được thêm vào response.
Conditional Relationships (Mối quan hệ có điều kiện)
Laravel giúp dễ dàng thêm mối quan hệ có điều kiện vào các resource response nếu mối quan hệ đã được tải trên model. whenLoaded đã được cung cấp để thực hiện điều này.
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'comments' => CommentResource::collection($this->whenLoaded('comments')),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
Ở đây trong ví dụ trên, nếu mối quan hệ của "comments " không được tải thì toàn bộ "comments " sẽ bị xóa khỏi response. Cũng lưu ý ở đây rằng phương thức whenLoaded chấp nhận tên của mối quan hệ thay vì chính mối quan hệ đó. Điều này là để tránh việc tải các mối quan hệ một cách không cần thiết.
Bình luận (0)