Quay lại
Polymorphic types trong Laravel's Eloquent

Khi làm việc với các mối quan hệ đa hình (polymorphic relationships) trong Eloquent của Laravel, điều quan trọng là phải chỉ định “loại” của related model. Bạn có thể thực hiện việc này bằng cách sử dụng các phương thức morphOne, morphManymorphToMany.

Giả sử chúng ta có các BookAuthor models có chung mối quan hệ đa hình (polymorphic) với Rating model. Và cấu trúc bảng của tất cả những thứ này sẽ như sau.

books
    id - integer
    name - string

authors
    id - integer
    name - string

ratings
    id - integer
    url - string
    ratingable_id - integer
    ratingable_type - string

Ở đây, như bạn có thể biết, cột ratingable_type của bảng ratings sẽ xác định “type” nào của parent model sẽ trả về khi truy cập vào ratingable relation.

Vì vậy, ví dụ: Nếu bạn muốn chỉ định điều này vào Book model, bạn có thể thực hiện bằng phương pháp morphOne như sau.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Rating extends Model
{
    /**
     * Get the parent ratingable model (book or author).
     */
    public function ratingable()
    {
        return $this->morphTo();
    }
}

class Book extends Model
{
    /**
     * Get the book's rating.
     */
    public function rating()
    {
        return $this->morphOne(Rating::class, 'ratingable');
    }
}

Bây giờ, như bạn có thể thấy, chúng ta đã chỉ định “type” trong morphOne làm tên class đủ điều kiện (FQCN) của model. Tuy nhiên, chúng ta có thể làm điều này theo cách tốt hơn bằng cách sử dụng thứ gọi là “map morphing”.

Polymorphich Types

Có một cách khác để bạn có thể “map-(ánh xạ)” các FQCN này thành chuỗi bằng cách sử dụng phương thức morphMap của Illuminate\Database\Eloquent\Relations\Relation. Bạn có thể đăng ký điều này trong phương thức boot của lớp App\Providers\AppServiceProvider của bạn.

Vì vậy, nếu bạn muốn ánh xạ/bí danh (map/alias) App\Models\Rating thành rating string, bạn có thể làm như sau.

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Relations\Relation;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Relation::morphMap([
            'rating' => 'App\Models\Rating',
        ]);
    }
}

Và bây giờ bạn có thể chỉ định rating là loại đa hình thay vì đưa ra FQCN như sau.

class Book extends Model
{
    /**
     * Get the book's rating.
     */
    public function rating()
    {
        return $this->morphOne('rating', 'ratingable');
    }
}

Benefits của sử dụng aliasing types

Lợi ích chính của kiểu đa hình bí danh (aliasing polymorphic type) là…

  • Bạn có một vị trí trung tâm nơi bạn có thể quản lý các loại đa hình của mình.
  • Vì bạn đang đặt bí danh cho các models dưới dạng chuỗi từ vị trí trung tâm nên giờ đây bạn có thể đổi tên các models một cách an toàn. Bằng cách đó, bạn không cần phải đi đến nhiều nơi chỉ để đổi tên các lớp.

Thận trọng khi sử dụng “map morph”

Điều quan trọng cần lưu ý ở đây là khi bạn bắt đầu sử dụng “map morph” trong ứng dụng hiện tại của mình, mọi giá trị cột *_type (ratingable_type  trong ví dụ của chúng ta) trong cơ sở dữ liệu của bạn vẫn chứa class đủ điều kiện sẽ cần phải được chuyển đổi thành class đó. tên “map”.

Bình luận (0)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Bài viết liên quan

Learning English Everyday