# Introduction
學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法
; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣造一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。
# Defining Relationships
# One To One
在 Laravel relationship 當中, 如何建立一個 one to one relation?
<?php |
Laravel hasOne relationship 當中, 預設 foreign key 的條件是什麼?
model name
Laravel hasOne relationship 當中, 如果我要自定義 foreign key, 我可以怎麼做?
<?php |
Laravel hasOne relationship 當中, 預設 foreign key 的值需要對應 parent table 上的哪一個 column 的值?
id
以下的 Laravel example code 的意思是?
Example:
<?php
return $this->hasOne('App\Phone', 'foreign_key', 'local_key');Answer:
自定義要使用哪個 owner table 與 foreign table 上的 key 來做連結, local_key 代表在 owner table, 即 $this, 上的 column name, foreign_key 代表在 ‘App\Phone’ table 上的 column
# Defining The Inverse Of The Relationship
Laravel one to one relationship 中, 如何定義反向的存取?
<?php |
Laravel one to one relationship 中, 預設定義 belongsTo 的 foreign key 的規則是?
根據 belongsTo method 的名稱, 在 method 名稱後加上 _id
Laravel one to one relationship 中, 如何自訂義 foreign key?
<?php |
Laravel one to one relationship 當中, 在 belongsTo method 當中, 如果我的 parent table 不是使用 id
作為 primary key, 而我想要自定義, 我可以怎麼做?
<?php |
# One To Many
Laravel one to many relationship 中, 如果我要建立一個 one to many 的 relation, 我可以怎麼做?
<?php |
以下的 relation 中, foreign key 預設是什麼?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function comments()
{
return $this->hasMany('App\Comment');
}
}Answer:
post_id, 預設, Laravel 會在擁有者 model 使用 “snake_case”, 並在最後加上_id
Laravel one to many relationship 中, 如何取得 relation?
<?php
$comments = App\Post::find(1)->comments;
foreach ($comments as $comment) {
//
}
Laravel one to many relationship 中, 如何取得 relation 的 query builder?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
return $this->hasMany('App\Comment', 'foreign_key');
return $this->hasMany('App\Comment', 'foreign_key', 'local_key');Answer:
定義 one to many relation 時, 指定 foreign_key 以及 local_key
### # One To Many (Inverse) ###### **Laravel one to many relation 中, 如何定義一個反向的 relation?**
<?php |
Laravel one to many relationship 中, 如何自訂義 foreign key 以及 primary key?
<?php |
# Many To Many
Laravel Relationship 中, 當我要建立一個 many to many 的中間表格, 表格的命名是什麼規格?
alphabetical
Laravel Relationship 中, 當我要建立一個 users, roles 的 many to many 的中間表格, 中間表格必須至少有什麼 column?
user_id, role_id
Laravel Relationship 中, 當我要建立一個 users, roles 的 many to many 的 relationship, 在 User 的 model 中, 我可以怎麼做?
<?php |
承上面 Laravel 程式碼, 在 Laravel Relationship 中, 如果我已經在 User 跟 Role model 之間建立了 many to many relationship, 當我想要從 user model 取 roles, 我可以怎麼做?
<?php |
承上面 Laravel 程式碼, 在 Laravel Relationship 中, 如果我已經在 User 跟 Role model 之間建立了 many to many relationship, 當我想要取 roles 並 chain query 時, 我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function roles()
{
return $this->belongsToMany('App\Role', 'table_name');
}
}Answer:
定義 User belongsTo Role relation, 並指定 pivot table 為 ‘table_name’
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function roles()
{
return $this->belongsToMany('App\Role', 'role_user', 'currentModel', 'joiningToModel');
}
}Answer:
定義 pivot table name, pivot table 上代表 current model 的 column 以及 foreign model 上的 column
在 Laravel many to many relationship 中, 如果我想要自定義中間表格中 column 的名稱, 我可以怎麼做?
# Retrieving Intermediate Table Columns
在 Laravel many to many relationship 中, 如果我想要取得中間表格的資料, 我可以怎麼做?
<?php |
在 Laravel many to many relationship 中, 當我取得 related model, related model 預設會載入中間 model 嗎?
會哦
在 Laravel many to many relationship 中, 當我取得 related model, 自動載入的中間 model 預設只會有什麼資料?
model key
在 Laravel many to many relationship 中, 當我取得 related model, 自動載入的中間 model 預設只會有 model key, 如果我想要讓他自動載入時自動載入其他特定 column 的資料, 我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function roles()
{
return $this->belongsToMany('App\Role')->withTimestamps();
}
}Answer:
使用 withTimestamps method, Model User 與 Model Role 的 many to many relationship 的 pivot table 上的 created_at 以及 updated_at 會被自動維護
# Customizing The pivot
Attribute Name
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function roles()
{
return $this->belongsToMany('App\Podcast')
->as('subscription')
->withTimestamps();
}
}Answer:
定義 pivot table name 為 subscription, 且自動維護 pivot table 的 created_at 以及 updated_at
呈上, 如何存取這個 subscription 中間表格?
<?php |
# Filtering Relationships Via Intermediate Table Columns
以下的 Laravel example code 的意思是?
Example:
<?php
return $this->belongsToMany('App\Role')->wherePivot('approved', 1);
return $this->belongsToMany('App\Role')->wherePivotIn('priority', [1, 2]);
return $this->belongsToMany('App\Role')->wherePivotNotIn('priority', [1, 2]);Answer:
<?php
// 定義了 $this 與 'App\Role' 的 belongsToMany relationship
// 除了 primary key 與 foreign key 條件符合之外
// 還需 wherePivot('approved', 1) 的條件滿足, 才算是此 relationship 的範圍
return $this->belongsToMany('App\Role')->wherePivot('approved', 1);
// 還需 wherePivotIn('priority', [1, 2]) 的條件滿足, 才算是此 relationship 的範圍
return $this->belongsToMany('App\Role')->wherePivotIn('priority', [1, 2]);
// 還需 wherePivotNotIn('priority', [1, 2]) 的條件滿足, 才算是此 relationship 的範圍
return $this->belongsToMany('App\Role')->wherePivotNotIn('priority', [1, 2]);
# Defining Custom Intermediate Table Models
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\User')->using('App\RoleUser');
}
}Answer:
在定義 many to many relation 的同時, 指定 pivot Model
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\User')
->using('App\RoleUser')
->withPivot([
'created_by',
'updated_by',
]);
}
}Answer:
在定義 Role belongsToMany User 的 relation 的同時, 指定 pivot table, 且指定 pivot table 上預設載入 ‘created_by’, 以及 ‘updated_by’ column
Laravel many to many relation 中, pivot model 可以使用 SoftDeletes trait 嗎?
不行哦
# Custom Pivot Models And Incrementing IDs
Laravel many to many relation 中, 為了讓 table 中的 primary key 運作正常, pivot model 中需要加什麼屬性?
<?php |
# Has One Through
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Supplier extends Model
{
public function userHistory()
{
return $this->hasOneThrough('App\History', 'App\User');
}
}Answer:
Supplier hasOne User, 而 User hasOne History, 第一個參數為目標 model
, 第二個參數為中間 model
, 定義好後可從 Supplier 直接取得 History model以下的 Laravel example code 的意思是?
Example:
<?php
Supplier extends Model
{
public function userHistory()
{
return $this->hasOneThrough(
'App\History',
'App\User',
'supplier_id', // Foreign key on users table...
'user_id', // Foreign key on history table...
'id', // Local key on suppliers table...
'id' // Local key on users table...
);
}
}Answer:
使用 hasOneThrough relation, 並定義 local key 以及 foreign key
# Has Many Through
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough('App\Post', 'App\User');
}
}Answer:
Country hasOne User, 而 User hasOne Post, 第一個參數為目標 model
, 第二個參數為中間 model
, 定義好後可從 Country 直接取得 Post model
在 Laravel one to many through method 中, 如果我要自定義 foreign key 以及 local key, 我可以怎麼做?
<?php |
# Polymorphic Relationships
# One To One (Polymorphic)
# Table Structure
在 Laravel 中, 如果說我有一個 image model, 而 user model 跟 post model 都跟 image 有 one to one 的關係, 那我可以使用什麼樣的 relation?
One To One (Polymorphic)
Laravel 中, 假設我的 Post model 有一個 Image model, 而 User model 也有一個 Image model, 現在我要定義 one to one (polymorphic) relation, 若要在 Post model 中定義與 Image model 的關係, 可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function image()
{
return $this->morphOne('App\Image', 'imageable');
}
}Answer:
User hasOne Image, 而其他 model 也有 hasOne Image relationship, 這樣就可以使用 morph relation, 可以共用一個 images table, Image model 的不同 relation 會在 ‘imageable_type’ 做區分, 例如 ‘App\User’ 或是 ‘App\Post’
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
public function imageable()
{
return $this->morphTo();
}
}Answer:
定義一個 polymorphic one to one 的 relation, Image model 可同時 belongs to 一個以上的 model
以下的 Laravel one to one (Polymorphic) relation table structure 當中, imageable_id 跟 imageable_type 分別代表什麼?
Example:
posts
id - integer
name - string
users
id - integer
name - string
images
id - integer
url - string
imageable_id - integer
imageable_type - stringAnswer:
imageable_id: user_id 或 post_id
imageable_type: user model name 或 post model name
# Retrieving The Relationship
在 Laravel one to one (Polymorphic) relation 當中, 假設以下為我的 relation 定義, 如果我要從 parent model 拿到 child model, 那我可以怎麼做?
Relation 定義:
<?php
class Post extends Model
{
public function image()
{
return $this->morphOne('App\Image', 'imageable');
}
}取得 relation:
<?php
$post = App\Post::find(1);
$image = $post->image;在 Laravel one to one (Polymorphic) relation 當中, 假設以下為我的 relation 定義, 如果我要從 child model 取得 parent model, 我可以怎麼做?
Relation 定義:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
/**
* Get the owning imageable model.
*/
public function imageable()
{
return $this->morphTo();
}
}取得 relation
<?php
$image = App\Image::find(1);
$imageable = $image->imageable;
# One To Many (Polymorphic)
# Table Structure
Laravel 當中, 如果說在我的應用中的 user 可以同時在 video 以及 post 中留下 comments, 那我可以使用怎麼樣的 relation?
one to many (Polymorphic)
Laravel one to many (Polymorphic) 當中, 以下的 table structure 中的 commentable_id 以及 commentable_type 代表什麼?
posts |
- commentable_id: 代表 foreign key
- commentable_type: 代表 relation 的 model name
#### # Model Structure ###### **Laravel 當中, 假設每一個 Video model 以及 Post model 都有多個 Comment model, 現在我要定義一個 one to many (polymorphic) relation, 若要從 Video model 中定義與 Comment model 的 relation, 可以怎麼做?**
<?php |
Laravel 當中, 假設每一個 Video model 以及 Post model 都有多個 Comment model, 現在我要定義一個 one to many (polymorphic) relation, 若要從 Post model 中定義與 Comment model 的 relation, 可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}Answer:
Comment model 同時與一個以上的 model 有 belongsTo 的 relation, 所以可以使用 polymorphic relation, 當使用 commentable relation 時, 會經由 commentable_type 以及 commentable_id 取得相對應的 relational model 以及 id
# Retrieving The Relationship
Laravel one to many (Polymorphic) relation 當中, 如果我要從 parent model 取得 child model, 我可以怎麼做? 假設以下為我的 relation 定義
Relation 定義:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
/**
* Get the owning commentable model.
*/
public function commentable()
{
return $this->morphTo();
}
}
class Post extends Model
{
/**
* Get all of the post's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}
class Video extends Model
{
/**
* Get all of the video's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}取得 relation
<?php
$post = App\Post::find(1);
foreach ($post->comments as $comment) {
//
}
在 Laravel one to many (Polymorphic) relation 當中, 假設以下為我的 relation 定義, 現在我要從 child model 取得 parent model, 那我可以怎麼做?
relation 定義:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
/**
* Get the owning commentable model.
*/
public function commentable()
{
return $this->morphTo();
}
}
class Post extends Model
{
/**
* Get all of the post's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}
class Video extends Model
{
/**
* Get all of the video's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}取得 relation
<?php
$comment = App\Comment::find(1);
$commentable = $comment->commentable;
# Many To Many (Polymorphic)
# Table Structure
在 Laravel many to many (Polymorphic) relation 當中, 假如說我有 video 跟 post model, 而兩者都跟 tag model 有 many to many 的關係, 那我可以怎樣定義我的 table?
posts |
# Model Structure
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function tags()
{
return $this->morphToMany('App\Tag', 'taggable');
}
}Answer:
定義 Post model 跟 Tag model 之間 polymorphic many to many relation
試想, 一篇 post 可以有多個 tags, 而我也可以經由一個 tag 取得多個 posts, 這樣就構成 many to many relationship
同時, 一部 video 可以有多個 tags, 而我也可以經由一個 tag 取得多部 video, 這樣也構成 many to many relationship
那我需要建立兩個 tags table 以及兩個 pivot table 嗎? 可以使用 polyMorphic many to many relation, 這樣只需要一個 tags table 以及一個 pivot table 就夠了
# Defining The Inverse Of The Relationship
以下的 Laravel example code 的意思是?
Example:
<?php
class Tag extends Model
{
public function posts()
{
return $this->morphedByMany('App\Post', 'taggable');
}
public function videos()
{
return $this->morphedByMany('App\Video', 'taggable');
}
}Answer:
定義 tags 分別與 videos 以及 posts table 之間的 polymorphic many to many relationship
試想, 一篇 post 可以有多個 tags, 而我也可以經由一個 tag 取得多個 posts, 這樣就構成 many to many relationship
同時, 一部 video 可以有多個 tags, 而我也可以經由一個 tag 取得多部 video, 這樣也構成 many to many relationship
那我需要建立兩個 tags table 以及兩個 pivot table 嗎? 可以使用 polyMorphic many to many relation, 這樣只需要一個 tags table 以及一個 pivot table 就夠了
在 Laravel many to many polymorphic relation 當中, 假如我有 Post 跟 Video model, 而兩者都與 Tag model 有 many to many 的 relationship, 現在我要在 Tag 定義 many to many polymorphic relation, 我可以怎麼做?
# Retrieving The Relationship
Laravel many to many polymorphic relationship 當中, 如果我的 relation 定義如下, 現在我要從 Post model 取得 Tag relation, 我該怎麼做?
Relation 定義:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany('App\Tag', 'taggable');
}
}Answer:
<?php
$post = App\Post::find(1);
foreach ($post->tags as $tag) {
//
}
Laravel many to many polymorphic relationship 當中, 如果我的 relation 定義如下, 現在我要從 Tag model 取得 Post relation, 我該怎麼做?
Relation 定義:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
/**
* Get all of the posts that are assigned this tag.
*/
public function posts()
{
return $this->morphedByMany('App\Post', 'taggable');
}
/**
* Get all of the videos that are assigned this tag.
*/
public function videos()
{
return $this->morphedByMany('App\Video', 'taggable');
}
}Answer:
<?php
$tag = App\Tag::find(1);
foreach ($tag->videos as $video) {
//
}
# Custom Polymorphic Types
在 Laravel polymorphic relationship 當中, 預設 commentable_type 的內容會是像什麼樣的?
model 的名稱, 像是 App\Post
或是 App\Video
在 Laravel polymorphic relationship 當中, polymorphic 關係的對應預設是依照 polymorphic type column 中的值來對應的, 格式預設是 App/ModelName
, 如果我不想要使用這個預設格式, 我想要變更的話, 我可以在什麼地方
變更?
AppServiceProvider
的 boot
function 內
在 Laravel polymorphic relationship 當中, 如果我要在 AppServiceProvider
當中自定義 polymorphic table 中的 type column 的值, 我可以怎麼做?
<?php |
在 Laravel polymorphic relationship 當中, 如果我在 AppServiceProvider
當中自定義 polymorphic table 中的 type column 的值之後, 原本的 App\Post
形式的 model 名稱需要依照自定義的名稱做變更嗎?
需要哦
# Querying Relations
以下的 Laravel example code 的意思是?
Example:
<?php
use Illuminate\Database\Eloquent\Builder;
$user->posts()
->where(function (Builder $query) {
return $query->where('active', 1)
->orWhere('votes', '>=', 100);
})
->get();
// select * from posts
// where user_id = ? and (active = 1 or votes >= 100)Answer:
使用 where function, 在其 closure 內限制 where constraints 的範圍
# Querying Relationship Existence
在 Laravel relationship 當中, 假如我的 Post model 與 Comment model 關聯, 我只要取得至少有一個 Comment 的 Post, 那我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
$posts = App\Post::has('comments', '>=', 3)->get();Answer:
取得有 3 個以上 (含 3 個) 的 Post model
在 Laravel relationship 當中, 假如我的 Post model 與 Comment model 關聯, 我只要取得有至少一個以上 Comment 的 Post, 且這個 comment 的 content 要含有 ‘foo’, 那我可以怎麼做?
<?php |
在 Laravel relationship 當中, 假如我的 Post model 與 Comment model 關聯, 我只要取得有十個以上 Comment 的 Post, 且 10 個 Comment 的 content 都要含有 ‘foo’, 那我可以怎麼做?
<?php |
# Querying Relationship Absence
在 Laravel relationship 當中, 假如我的 Post model 與 Comment model 關聯, 我要取得沒有任何 comments 的 post, 那我可以怎麼做?
<?php |
在 Laravel relationship 當中, 假如我的 Post model 與 Comment model 關聯, 我要取得沒有某些特定 comment 的 post, 而這些特定的 comment 的 content 會含有 ‘foo’, 那我可以怎麼做?
<?php |
在 Laravel relationship 中, 假設我有 post, comment, 以及 author Model, 現在我要取得 comment 的 author 未被 banned 的 post (以 post 的 comment 的 author 為條件 query), 那我可以怎麼做?
<?php |
# Querying Polymorphic Relationships
以下的 Laravel example code 的意思是?
Example:
<?php
use Illuminate\Database\Eloquent\Builder;
// Retrieve comments associated to posts or videos with a title like foo%...
$comments = App\Comment::whereHasMorph(
'commentable',
['App\Post', 'App\Video'],
function (Builder $query) {
$query->where('title', 'like', 'foo%');
}
)->get();Answer:
取得 polymorphic many to many relation 的 Post, Video relation, 並從中篩選 title 含有 ‘foo%’ 的 model
在 Laravel polymorphic relationship 當中, 假如 Post 與 Video Model 都有多個 Comment Model, 現在我要取得 comment, 所屬的 video 或 post 的 title
含有 foo%
, 那我可以怎麼做?
Laravel 中, 如果今天我的 Comment model 與 video 以及 post 有 polymorphic 的 relation, 那我想要取得 comment, 且該 comment 所屬的 post 的 title 不可含有 foo
, 那我可以怎麼做?
<?php |
Laravel 中, 假如 Post model, Video model 與 Comment model 有 polymorphic 的關係, 現在我想要取得某些 Comment, 條件是 Video 的 title 必須含有 foo
, 而 Post 的 title 或 content 必須含有 foo
, 那我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
use Illuminate\Database\Eloquent\Builder;
$comments = App\Comment::whereHasMorph('commentable', '*', function (Builder $query) {
$query->where('title', 'like', 'foo%');
})->get();Answer:
一次性取得所有的 morph model, 不管我有幾個, 並且從這些 relation 當中搜尋任何 title 含有foo
的 comment
# Counting Relate Models
Laravel relationship 中, 假設今天我的 Post model 有很多 Comment model, 我想要拿到每個 Post model 下有幾個 Comment model, 那我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
use Illuminate\Database\Eloquent\Builder;
$posts = App\Post::withCount(['votes', 'comments' => function (Builder $query) {
$query->where('content', 'like', 'foo%');
}])->get();
echo $posts[0]->votes_count;
echo $posts[0]->comments_count;Answer:
取出 Post model 的 relation model ‘Votes’, 以及 ‘Comments’ 的數量, 並且, 針對 Comments model 有特別篩選, 條件為 where(‘content, ‘like’, ‘foo%’)
載入後, 可在每一個 Post model 使用 ‘votes_count’ 以及 ‘comments_count’
Laravel relationship 中, 當我使用了 withCount method, Laravel 會在取得的 model 中加入哪一個欄位?
{relation}_count
以下的 Laravel example code 的意思是?
Example:
<?php
use Illuminate\Database\Eloquent\Builder;
$posts = App\Post::withCount([
'comments',
'comments as pending_comments_count' => function (Builder $query) {
$query->where('approved', false);
},
])->get();
echo $posts[0]->comments_count;
echo $posts[0]->pending_comments_count;Answer:
取得兩種 Post model 的 relation Comment model count, 一個有加特定 constraints, 並 alias 為 pending_comments_count
Laravel relationship 中, 假設今天我的 Post model 有 comments 的 relationships, 假如現在我要取得每個 Post 有幾個 comment, 以及我要自定義一個 comment 叫做 pending_comments_count
, 條件是該 comment 的 approved
必須是 false
, 那我可以怎麼做?
Laravel Query Builder 當中, 如果我要同時使用 select
以及 withCount
, 哪一種需排在前面?
select
以下的 Laravel example code 的意思是?
Example:
<?php
$posts = App\Post::select(['title', 'body'])->withCount('comments')->get();
echo $posts[0]->title;
echo $posts[0]->body;
echo $posts[0]->comments_count;Answer:
使用 select() 取得 title, body column
使用 withCount() 取得 comments relation 的數量
Laravel 當中, 如果我的 Book model 有很多 genres
model relation, 現在我已取得特定的那一個 Book model, 我要再取得所屬的 genres
的數量, 那我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
$book->loadCount(['reviews' => function ($query) {
$query->where('rating', 5);
}])Answer:
取得 $book 的 Reviews relation model 的數量, 並針對 Reviews model 使用where('rating', 5)
做篩選
# Eager Loading
以下的 Laravel 程式碼中, author 為 book model 的 relation, 假設 $books 有 25 個 book model, 那以下的程式碼共會 query 幾次?
程式碼:
<?php
$books = App\Book::all();
foreach ($books as $book) {
echo $book->author->name;
}answer:
26 次, 取所有的 book model 共花一次, 取各個 model 的 author relation 再花 25 次Laravel 中, 假設以下為我的原始程式碼, 我要如何使用 eager loading 將所有的 author relation 一次取出?
原始程式碼:
<?php
$books = App\Book::all();
foreach ($books as $book) {
echo $book->author->name;
}Answer:
<?php
$books = App\Book::with('author')->get();
foreach ($books as $book) {
echo $book->author->name;
}
以下的 Laravel 程式碼中, 實際上下的 MySQL query 是哪兩句?
程式碼:
<?php
$books = App\Book::with('author')->get();
foreach ($books as $book) {
echo $book->author->name;
}query 語法:
select * from books
select * from authors where id in (1, 2, 3, 4, 5, ...)
# Eager Loading Multiple Relationships
在以下的 Laravel 程式碼中, 我如果想要一次性的 eager load relations author
跟 publisher
, 我可以怎麼做?
程式碼:
<?php
$books = App\Book::all();
foreach ($books as $book) {
echo $book->author->name;
}Answer:
<?php
$books = App\Book::with(['author', 'publisher'])->get();
#### # Nested Eager Loading ###### **以下的 Laravel example code 的意思是?**Example:
<?php
$books = App\Book::with('author.contacts')->get();Answer:
eager load Book model 的 relation author, 以及 author 的 relation contacts
#### # Nested Eager Loading `morphTo` Relationships ###### **以下的 Laravel example code 的意思是?**Example:
<?php
use Illuminate\Database\Eloquent\Relations\MorphTo;
$activities = ActivityFeed::query()
->with(['parentable' => function (MorphTo $morphTo) {
$morphTo->morphWith([
Event::class => ['calendar'],
Photo::class => ['tags'],
Post::class => ['author'],
]);
}])->get();Answer:
ActivityFood morphTo Event
ActivityFood morphTo Photo
ActivityFood morphTo Post
Event has relation with calendar
Photo has relation with tags
Post has relation with author
一次性的從 ActivityFeed eager loading 上面的六個 relationships
# Eager Loading Specific Columns
在以下的 Laravel 程式碼中, 如果我只想要 eager load author relation 中的 id 以及 name columns, 我可以怎麼做?
程式碼:
<?php
$books = App\Book::all();
foreach ($books as $book) {
echo $book->author->name;
}Answer:
<?php
$books = App\Book::with('author:id,name')->get();在 Laravel 當中, 如果說我今天使用 eager loading 來取得部份的 column, 有哪一個 column 是必須的?
id
# Eager Loading By Default
在以下的 Laravel relation definition 當中, 如果說我想要預設 eager load author
這一個 relation, 那我可以怎麼做?
Relation definition:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
/**
* Get the author that wrote the book.
*/
public function author()
{
return $this->belongsTo('App\Author');
}
}Answer:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
/**
* The relationships that should always be loaded.
*
* @var array
*/
protected $with = ['author'];
/**
* Get the author that wrote the book.
*/
public function author()
{
return $this->belongsTo('App\Author');
}
}
在以下的 Laravel relation definition 當中, 如果說我想要從某次的 query 當中移除 $with
所賦予的 default eager loading
效果, 那我可以怎麼做?
Relation definition:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
protected $with = ['author'];
public function author()
{
return $this->belongsTo('App\Author');
}
}Answer:
<?php
$books = App\Book::without('author')->get();
# Constraining Eager Loads
在以下的 Laravel eager loading 範例程式碼中, 如果我想要指定 eager load title
含有 first
的 posts
model, 那我可以怎麼做?
範例程式碼:
<?php
$users = App\User::with('posts')->get();Answer:
<?php
$users = App\User::with(['posts' => function ($query) {
$query->where('title', 'like', '%first%');
}])->get();
在以下的 Laravel 範例程式碼中, 我可以加入額外的 query builder
method 嗎?
範例程式碼:
<?php
$users = App\User::with(['posts' => function ($query) {
$query->where('title', 'like', '%first%');
}])->get();Answer:
可以
Laravel eager loading constrain 當中, 像是以下的 Laravel 範例程式碼, 有哪些 query builder method 不適用?
範例:
<?php
$users = App\User::with(['posts' => function ($query) {
$query->orderBy('created_at', 'desc');
}])->get();Answer:
limit
及take
# Lazy Eager Loading
假如我的 Book
model 有 author
以及 publisher
的 relation, 但我想要在特定的條件下才 eager load relation 如以下的範例程式碼, 那我可以怎麼做?
範例程式碼:
<?php
$books = App\Book::all();
if ($someCondition) {
// eager load here
}Answer:
<?php
$books = App\Book::all();
if ($someCondition) {
$books->load('author', 'publisher');
}以下的 Laravel example code 的意思是?
Example:
<?php
$author->load(['books' => function ($query) {
$query->orderBy('published_date', 'asc');
}]);Answer:
eager load author 的 books relation model, 並且針對 books model 做 orderBy 排序以下的 Laravel example code 的意思是?
Example:
<?php
public function format(Book $book)
{
$book->loadMissing('author');
return [
'name' => $book->name,
'author' => $book->author->name,
];
}Answer:
假設我們在一開頭就取出了 User model 的 Author relation model ‘$user = User::with(‘author)’
然而, $user 後面又新增了 Author relation model ‘$user->authors()->attach($newAuthor)’
這時 $user 上原本載入的 Author model 就沒有這個新的 $newAuthor, 這時就可以使用 loadMissing()
#### # Nested Lazy Eager Loading & `morphTo` ###### **Laravel 中, 假設我有一個 ActivityFeed Model, 它跟 `Event`, `Photo`, `Post` Model 有 `morphTo` 的關係, 如下面範例。 而 `Event` 又與 `Calendar` 有關, `Photo` 與 `Tag` 有關, 而 `Post` 與 `Author` 有關。 現在我要先 eager load ActivityFeed 的 `morphTo` 關係, 再使用 lazy eager loading 取得以上 `morphTo` 各自的 relationship, 我可以怎麼做?**範例 relation:
<?php
use Illuminate\Database\Eloquent\Model;
class ActivityFeed extends Model
{
/**
* Get the parent of the activity feed record.
*/
public function parentable()
{
return $this->morphTo();
}
}Answer:
<?php
$activities = ActivityFeed::with('parentable')
->get()
->loadMorph('parentable', [
Event::class => ['calendar'],
Photo::class => ['tags'],
Post::class => ['author'],
]);
# Inserting & Updating Related Models
# The save
method
以下的 Laravel example code 的意思是?
範例程式碼:
<?php
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);
$post->comments()->save($comment);Answer:
使用帶入 model 的方式來新增 relation
在 Laravel 當中, 在以下的範例程式碼當中, 我要如何一次儲存複數的 model?
範例程式碼:
<?php
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);
$post->comments()->save($comment);Answer:
<?php
$post = App\Post::find(1);
$post->comments()->saveMany([
new App\Comment(['message' => 'A new comment.']),
new App\Comment(['message' => 'Another comment.']),
]);
# Recursively Saving Models & Relationships
以下的 Laravel 程式碼代表什麼意思?
程式碼:
<?php
$post = App\Post::find(1);
$post->comments[0]->message = 'Message';
$post->comments[0]->author->name = 'Author Name';
$post->push();Answer:
指定 post 的 comment relation 的第一個 model 的 message 為 ‘Message’
指定 post 的 comment relation 的第一個 model 的 author relation 的 name 為 ‘Author Name’
Laravel 當中, 如果我的 relation 是 Post->hasMany->comment, 現在我要變更第一個 comment 的 message 欄位為 ‘Message’, 以及 comment 的 author relation 的 name 欄位為 ‘Author Name’, 我可以怎麼做?
<?php |
# The create
Method
Laravel relationship 當中, save 跟 create method 的差別在於?
- save 接受的參數為 model
- create 接受的參數為 array
以下的 Laravel 程式碼代表什麼意思?
程式碼:
<?php
$post = App\Post::find(1);
$comment = $post->comments()->create([
'message' => 'A new comment.',
]);Answer:
使用 array 內的資料來建立一筆 Post 與 Comment 的關係
以下的 Laravel example code 的意思是?
Example:
<?php
$post = App\Post::find(1);
$comment = $post->comments()->create([
'message' => 'A new comment.',
]);Answer:
使用 create(), 帶入 array 來建立 Post hasMany Comment relation
以下的 Laravel 程式碼中, 該怎麼儲存 post 與 comment 的 relation?
程式碼:
<?php
$post = App\Post::find(1);
$comment = ['message' => 'A new comment.'];Answer:
<?php
$post = App\Post::find(1);
$comment = ['message' => 'A new comment.'];
$comment = $post->comments()->create($comment);
以下的 Laravel example code 的意思是?
Example:
<?php
$post = App\Post::find(1);
$post->comments()->createMany([$comment1, $comment2]);Answer:
使用 createMany(), 帶入多個 array 來建立多個 Comments model 並儲存於資料庫, Post model hasMany Comment model
如果我要使用多個 array 來建立 relation, 我可以使用哪一個 method?
createMany
# Belongs To Relationships
以下的 Laravel 程式碼是什麼意思?
程式碼:
<?php
$account = App\Account::find(10);
$user->account()->associate($account);
$user->save();Answer:
取得目標 account
在該 user 的 account relation 中新增上面取得的 account model
以下的 Laravel 程式碼是什麼意思?
程式碼:
<?php
$manager = auth()->user();
$sub_account->manager()->dissociate();
$sub_account->save();Answer:
sub_account belongs to manager
將 sub_account 的 foreign key 設為 null以下的 Laravel 程式碼是什麼意思?
程式碼:
<?php
$manager = auth()->user();
$sub_account->manager()->associate($manager);
$sub_account->save();Answer:
sub_account belongs to manager
將 sub_account 的 foreign key 設為 $manager以下的 Laravel 程式碼中, $manager 可以是什麼?
程式碼:
<?php
$manager = auth()->user();
$sub_account->manager()->associate($manager);
$sub_account->save();Answer:
Eloquent Model
也可以是任意字元, 會儲存在 foreign keyLaravel relation 當中, 如果我要更新 belongs to 的 relation, subAccount belongs to Manager, 如下面的程式碼中, 我已取得 manager 的 model, 除了直接使用 update method 去更新該 table 之外, 我可以使用哪個 method?
程式碼:
<?php
$manager = App\Manager::find(10);Answer:
<?php
$manager = App\Manager::find(10);
$sub_account->manager()->associate($manager);
$sub_account->save();
以下的 Laravel example code 的意思是?
Example:
<?php
$sub_account->manager()->dissociate();
$sub_account->save();Answer:
從 $sub_account 的 belongsTo relation manager model 中, 移除 foreign key, 即移除彼此的 relation
# Default Models
Laravel 當中, 哪些種類的 relation 可以定義 default model?
belongsTo
hasOne
hasOneThrough
morphOne
Laravel 當中, 如果我的 relation definition 如下, 現在我要定義一個 default model, name 為 guest author 我可以怎麼做?
範例程式碼:
<?php
/**
* Get the author of the post.
*/
public function user()
{
return $this->belongsTo('App\User');
}Answer 1:
<?php
/**
* Get the author of the post.
*/
public function user()
{
return $this->belongsTo('App\User')->withDefault([
'name' => 'Guest Author',
]);
}Answer 2:
<?php
/**
* Get the author of the post.
*/
public function user()
{
return $this->belongsTo('App\User')->withDefault(function ($user, $post) {
$user->name = 'Guest Author';
});
}以下的 Laravel relation definition, 如果該 relation 不存在, 會回傳什麼?
範例 relation definition:
<?php
/**
* Get the author of the post.
*/
public function user()
{
return $this->belongsTo('App\User')->withDefault([
'name' => 'Guest Author',
]);
}Answer:
{
"name": "Guest Author"
}
# Many To Many Relationships
# Attaching / Detaching
Laravel many to many relation 中, 如果我要單純新增一筆 relation 紀錄, 我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
$user->roles()->attach($roleId, ['expires' => $expires]);Answer:
為 $user model 新增指定的一筆 $roldId many to many relation, 並且額外指定要新增到 pivot table 中的 column/value
以下的 Laravel example code 的意思是?
Example:
<?php
$user->roles()->detach($roleId);Answer:
在 many to many relation 中, 移除該 User model 指定的一筆 Role relation model
Laravel many to many relation 中, 如果我要單純的移除多筆筆 relation 紀錄, 我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
$user->roles()->detach();Answer:
移除 $user 的 many to many relation Role 所有的 records, 相當於移除 pivot table 中所有 $user 的 role relation model
Laravel many to many relation 中, 如果我要新增多筆 relation 紀錄, 然後我還要再在額外的欄位寫入資訊, 那我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
$user->roles()->sync([1, 2, 3]);Answer:
在 many to many relation 中, 可使用 sync method, 資料庫會同步帶入的 parameters, 在此 example 中, 資料庫內如果沒有 1, 2, 3 則會新增, 並刪除除了 1, 2, 3 之外的資料
Laravel many to many relation 中, 帶入一筆或多筆 relation 紀錄, 資料庫內需與帶入的資料完全符合, 沒有的新增, 多的刪除, 我還要再額外的欄位新增資訊, 那我可以怎麼做?
<?php |
以下的 Laravel example code 的意思是?
Example:
<?php
$user->roles()->syncWithoutDetaching([1, 2, 3]);Answer:
如果資料庫並不存在 array 內的資料, 則新增
如果資料庫已存在 array 內的資料, 則保留
# Toggling Associations
Laravel many to many relation 中, 如果我要帶入一組 relation 紀錄, 資料庫裡頭, 若沒有則則新增, 若有的話則移除, 那我可以怎麼做?
<?php |
# Saving Additional Data On A Pivot Table
Laravel many to many relation 中, 如果我要新增一筆 relation 紀錄, 同時如果此 relation 的對象不存在的話則建立, 再建立 relation 紀錄, 那我可以怎麼做?
<?php |
# Updating A Record On A Pivot Table
以下的 Laravel example code 的意思是?
Example:
<?php
$user = App\User::find(1);
$user->roles()->updateExistingPivot($roleId, $attributes);Answer:
更新 many to many relation 的 pivot table, $attribute 為帶有 column/value 的 array
# Touching Parent Timestamps
以下的 Laravel example code 的意思是?
Example:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
protected $touches = ['post'];
public function post()
{
return $this->belongsTo('App\Post');
}
}Answer:
使用 $touches property, 這樣當我更新 pivot table 時, 也會一併的更新 Post model 中的 timestamp
留言