Eloquent: relationships in laravel-Phần 2
Phần 1: https://viblo.asia/trung.nn.92/posts/PdbGnoEdeyA Polymorphic Relations Cấu trúc bảng Quan hệ đa hình cho phép 1 model thuộc về nhiều hơn 1 model khác. Ví dụ, hãy tưởng tượng users của ứng dụng của bạn có thể "comments" cả post và video. Sử dụng các mối quan hệ đa hình, bạn có thể ...
Phần 1: https://viblo.asia/trung.nn.92/posts/PdbGnoEdeyA
Polymorphic Relations
Cấu trúc bảng
Quan hệ đa hình cho phép 1 model thuộc về nhiều hơn 1 model khác. Ví dụ, hãy tưởng tượng users của ứng dụng của bạn có thể "comments" cả post và video. Sử dụng các mối quan hệ đa hình, bạn có thể sử dụng 1 bảng comments duy nhất cho cả 2. Trước tiên, hãy kiểm tra các cấu trúc bảng cần thiết để xây dựng mối quan hệ này.
posts id - integer title - string body - text videos id - integer title - string url - string comments id - integer body - text commentable_id - integer commentable_type - string
Hai cột quan trọng cần lưu ý là cột commentable_id và commentable_type trong bảng comments. Cột commentable_id sẽ chứa giá trị id của post hoặc video. Trong khi cột commentable_type sẽ chứa tên lớp của model sở hữu. Cột commentable_type là cách ORM xác định "type" của model sở hữu sẽ trả về khi truy cập vào các mối quan hệ commentable.
Model Structure
Tiếp theo, hãy kiểm tra các định nghĩa model cần thiết để xây dựng mối quan hệ này:
<?php namespace App; use IlluminateDatabaseEloquentModel; class Comment extends Model { /** * Get all of the owning commentable models. */ public function commentable() { return $this->morphTo(); } } class Post extends Model { /** * Get all of the post's comments. */ public function comments() { return $this->morphMany('AppComment', 'commentable'); } } class Video extends Model { /** * Get all of the video's comments. */ public function comments() { return $this->morphMany('AppComment', 'commentable'); } }
Retrieving Polymorphic Relations
Mỗi khi bảng cơ sở dữ liệu và model của bạn được xác định, bạn có thể truy cập vào các mối quan hệ thông qua model của bạn. Ví dụ, để truy cập vào tất cả các comments cho một post, chúng ta có thể đơn giản sử dụng những property động:
$post = AppPost::find(1); foreach ($post->comments as $comment) { // }
Bạn cũng có thể truy xuất các chủ sở hữu của một mối quan hệ đa hình từ model đa hình bằng cách truy cập vào tên của method thực hiện gọi đến method morphTo. Trong trường hợp của chúng ta, đó là method commentable trên Comment model. Vì vậy, chúng ta sẽ tiếp cận phương pháp đó như là một property động:
$comment = AppComment::find(1); $commentable = $comment->commentable;
Các mối quan hệ commentable trên mô Comment model sẽ trả lại hoặc là một Post hay dụ Video instance, tùy thuộc vào loại mô hình sở hữu các comment.
Custom Polymorphic Types
Theo mặc định, Laravel sẽ sử dụng tên lớp đầy đủ để lưu trữ các loại model có liên quan. Ví dụ, với các ví dụ ở trên, nơi một comment có thể thuộc về một Post hoặc một Video, commentable_type mặc định sẽ là một trong hai AppPost hoặc AppVideo tương ứng. Tuy nhiên, bạn có thể muốn tách cơ sở dữ liệu của bạn từ cấu trúc bên trong của ứng dụng của bạn. Trong trường hợp đó, bạn có thể xác định một mối quan hệ "morph map" để hướng dẫn Eloquent để sử dụng một tên tùy chỉnh cho mỗi model thay vì tên lớp:
use IlluminateDatabaseEloquentRelationsRelation; Relation::morphMap([ 'posts' => AppPost::class, 'videos' => AppVideo::class, ]);
Bạn có thể đăng ký morphMap trong các boot function của AppServiceProvider của bạn hoặc tạo ra một service provider riêng biệt nếu bạn muốn.
Many To Many Polymorphic Relations
Table Structure
Ngoài mối quan hệ đa hình truyền thống, bạn cũng có thể định nghĩa "many-to-many" mối quan hệ đa hình. Ví dụ, một blog Postvà Video model có thể chia sẻ một mối quan hệ đa hình cho một Tag model. Sử dụng một mối quan hệ đa hình many-to-many cho phép bạn có một danh sách duy nhất của unique tags được chia sẻ trên các blog posts và videos. Trước tiên, hãy kiểm tra cấu trúc bảng:
posts id - integer name - string videos id - integer name - string tags id - integer name - string taggables tag_id - integer taggable_id - integer taggable_type - string
Model Structure
Tiếp theo, chúng ta đã sẵn sàng để xác định các mối quan hệ trên model. Các Post model và Video model cả hai sẽ có một tags method gọi phương thức morphToMany trên lớp base Eloquent:
<?php namespace App; use IlluminateDatabaseEloquentModel; class Post extends Model { /** * Get all of the tags for the post. */ public function tags() { return $this->morphToMany('AppTag', 'taggable'); } }
Defining The Inverse Of The Relationship
Tiếp theo, trên Tag model, bạn nên xác định một method cho mỗi model có liên quan của nó. Vì vậy, trong ví dụ này, chúng tôi sẽ xác định một posts method và video method:
<?php namespace App; use IlluminateDatabaseEloquentModel; class Tag extends Model { /** * Get all of the posts that are assigned this tag. */ public function posts() { return $this->morphedByMany('AppPost', 'taggable'); } /** * Get all of the videos that are assigned this tag. */ public function videos() { return $this->morphedByMany('AppVideo', 'taggable'); } }
Retrieving The Relationship
Khi bảng cơ sở dữ liệu và model của bạn được xác định, bạn có thể truy cập vào các mối quan hệ thông qua model của bạn. Ví dụ, để truy cập vào tất cả các tags cho một post, bạn chỉ có thể sử dụng các tags property động:
$post = AppPost::find(1); foreach ($post->tags as $tag) { // }
Bạn cũng có thể truy xuất các chủ sở hữu của một mối quan hệ đa hình từ model đa hình bằng cách truy cập vào tên của phương thức đó thực hiện các cuộc gọi đến morphedByMany. Trong trường hợp của chúng ta, đó là những posts hoặc videos method trên Tag model. Vì vậy, bạn sẽ truy cập vào các method đó là property động:
$tag = AppTag::find(1); foreach ($tag->videos as $video) { // }
Vậy là mình đã giới thiệu cho các bạn về các mối quan hệ trong Eloquent. Ở phần tiếp theo, mình sẽ tiếp tục giới thiệu cho các bạn về Querying Relations, Eager Loading và Inserting & Updating Related Models.