除了我們之前討論過的那些字段,Nova 還支持 Laravel 模型的關聯(lián)關系。只要給資源添加一個關聯(lián)關系,你就能體會到 Nova 的強大之處,因為你可以在資源詳情頁快速的查看并搜索該資源的關聯(lián)模型:
這個 HasOne
對應一個 hasOne
Eloquent 關系。例如,讓我們假設一個 User
模型 hasOne
Address
模型。我們可以將這種關系添加到我們的
User
Nova 資源中,如下所示:
use Laravel\Nova\Fields\HasOne;
HasOne::make('Address')
就像其他類型的字段一樣,關系字段將自動地 “snake case” 字段的顯示名稱,來確定底層關系的方法或?qū)傩?。然而,你可以將它作為第二個參數(shù)傳遞給這個字段的 make
方法,來明確地指定關系方法的名稱。如下所示:
HasOne::make('Dirección', 'address')
HasMany
字段對應 Eloquent 中的 hasMany
關系。假設一個 User
模型 hasMany
Post
模型,那么我們可以給 Nova 的 User
資源添加如下關系:
use Laravel\Nova\Fields\HasMany;
HasMany::make('Posts')
BelongsTo
字段對應 Eloquent 中的 belongsTo
關系。假設一個 Post
模型 belongsTo
一個 User
模型,那么我們可以給
Nova 的 Post
資源添加如下關系:
use Laravel\Nova\Fields\BelongsTo;
BelongsTo::make('User')
當創(chuàng)建或編輯包含 BelongsTo
字段的資源時,下拉框或搜索框里會顯示該資源的「標題」。假如 User
資源的標題是 name
屬性,那么 BelongsTo
選擇菜單里顯示的就是他的
name
:
如果要自定義資源的「titile」,可以在資源類里定義一個 title
屬性:
public static $title = 'name';
此外,你也可以覆蓋資源的 title
方法:
/**
* 獲取資源顯示的值。
*
* @return string
*/
public function title()
{
return $this->name;
}
BelongsToMany
字段對應于模型的 belongsToMany
關聯(lián)。例如,我們假定有一個 User
模型 belongsToMany
Role
模型。我們就可以像這樣將它添加到 User
Nova
資源中:
use Laravel\Nova\Fields\BelongsToMany;
BelongsToMany::make('Roles')
如果你的 belongsToMany
關聯(lián)中間表還存著其他的關聯(lián)字段,你也可以將它附到 BelongsToMany
Nova 關聯(lián)字段上。一旦這些字段被附到該關聯(lián),那他們將會在關聯(lián)資源列表中展示.
例如,我們假定我們的 User
模型 belongsToMany
Role
模型。在 role_user
中間表,讓我們想象一下 notes
字段包含一些關聯(lián)關系中簡單的文本 我們可以使用 fields
方法把這個字段附加到
BelongsToMany
字段上:
BelongsToMany::make('Roles')
->fields(function () {
return [
Text::make('Notes'),
];
});
當然,這也可以在定義相反關聯(lián)時使用。所以,如果我們在 User
資源中定義了一個 BelongsToMany
字段,我們也可以在 Role
資源中定義反向關聯(lián):
BelongsToMany::make('Users')
->fields(function () {
return [
Text::make('Notes'),
];
});
在兩處分別定義這樣的關聯(lián)可能會讓我們的代碼重復,Nova 允許你通過傳入一個可調(diào)用的對象給 fields
方法:
BelongsToMany::make('Users')->fields(new RoleUserFields)
上面的例子中,RoleUserFields
類可以只有一個 __invoke
方法,并返回一個包含附加字段的數(shù)組:
<?php
namespace App\Nova;
use Laravel\Nova\Fields\Text;
class RoleUserFields
{
/**
* 獲取關聯(lián)模型的附加字段
*
* @return array
*/
public function __invoke()
{
return [
Text::make('Notes'),
];
}
}
通常,Nova actions 是基于資源操作的。 然而,你也可以把 actions 綁定到 belongsToMany
字段 然后他們就可以在 pivot / 中間表記錄上操作了。為了實現(xiàn)它,你可以在字段定義時使用 actions
鏈式方法:
BelongsToMany::make('Roles')
->actions(function () {
return [
new Actions\MarkAsActive,
];
});
一旦 action 被綁定到這個字段,你就可以從父級資源屏幕上的關系索引中選擇這個 action 并且執(zhí)行它。
當 BelongsToMany
字段出現(xiàn)在資源創(chuàng)建和更新操作時,一個下拉選擇菜單或搜索框會顯示當前資源的 “title” 。例如: Role
資源可以使用 name
屬性作為其標題。然后,當資源顯示在 BelongsToMany
選擇菜單時,這個屬性也會顯示。
為了自定義這個資源的 “title” ,你可以在類內(nèi)定義一個 title
成員屬性:
public static $title = 'name';
另外,你可以復寫資源的 title
方法:
/**
* 獲取資源需要被顯示的值
* @return string
*/
public function title()
{
return $this->name;
}
MorphMany
字段響應 morphMany
Eloquent 關聯(lián)。例如:我們假設
Post
與 Comment
模型存在一對多的多態(tài)關聯(lián)。我們可以為 Post
Nova 資源添加關聯(lián),如下:
use Laravel\Nova\Fields\MorphMany;
MorphMany::make('Comments')
MorphTo
字段對應于 morphTo
Eloquent 關系。 例如,讓我們假設一個 Comment
模型與 Post
和 Video
模型都有多態(tài)關系。
我們可以將這種關系添加到我們的 Comment
Nova 資源中,如下所示:
use Laravel\Nova\Post;
use Laravel\Nova\Video;
use Laravel\Nova\Fields\MorphTo;
MorphTo::make('Commentable')->types([
Post::class,
Video::class,
])
正如上面的示例中所看到的,types
方法用于指示 MorphTo
字段可以與哪些類型的資源相關聯(lián)。 Nova 將使用此信息在創(chuàng)建和更新顯示 MorphTo
字段的類型選擇菜單:
多態(tài)標題屬性
當在資源創(chuàng)建 / 更新顯示
MorphTo
字段時,將自動顯示可用資源的 [標題屬性](#title-attributes)。
MorphToMany
字段對應于 morphToMany
Eloquent 關系。例如,讓我們假設一個 Post
模型與 Tag
模型有多對多多態(tài)關系。 我們可以將這種關系添加到我們的 Post
Nova 資源中,如下所示:
use Laravel\Nova\Fields\MorphToMany;
MorphToMany::make('Tags')
如果您的 morphToMany
關系與存儲在多對多關系的中間表中的其他 “pivot” 字段進行交互,則您也可以將其附加到 MorphToMany
Nova 關系中。將這些字段附加到關系字段后,它們將顯示在相關的資源索引上。
例如,在 taggables
中間表上,假設有一個 notes
字段,其中包含一些關于關系的簡單文本注釋。我們可以使用 fields
方法將此透視字段附加到 MorphToMany
字段:
MorphToMany::make('Tags')
->fields(function () {
return [
Text::make('Notes'),
];
});
當然,我們很可能也會在關系的反方向定義這個字段。 所以,如果我們在 Post
資源上定義 MorphToMany
字段,我們將在 Tag
資源中定義它的反向關聯(lián):
MorphToMany::make('Posts')
->fields(function () {
return [
Text::make('Notes'),
];
});
由于在關系的兩端定義字段會導致一些代碼重復,nova 允許您將可調(diào)用對象傳遞給 “fields” 方法:
MorphToMany::make('Users')->fields(new TaggableFields)
在這個例子中,’taggablefields’類是一個返回數(shù)組的核心字段的簡單、可調(diào)用的類,
<?php
namespace App\Nova;
use Laravel\Nova\Fields\Text;
class TaggableFields
{
/**
* Get the pivot fields for the relationship.
*
* @return array
*/
public function __invoke()
{
return [
Text::make('Notes'),
];
}
}
當 MorphToMany
字段顯示在資源創(chuàng)建 / 更新頁面上時,下拉選擇菜單或搜索菜單將顯示資源的 “標題”。例如,Tag
資源可以使用 name
屬性作為它的標題。然后,當資源在 MorphToMany
選擇菜單中顯示時,該屬性將顯示:
您可以在資源類上定義一個 title 屬性,自定義資源的 title 屬性值:
public static $title = 'name';
或者你可以重寫資源的 title
方法:
/**
* 獲取資源類顯示的標題。
*
* @return string
*/
public function title()
{
return $this->name;
}
在我們使用 BelongsTo、BelongsToMany、MorphTo、MorphToMany 來建立兩個模型的關聯(lián)關系時,Nova 會默認顯示一個簡單的下拉選擇欄。但是,當我們兩個關聯(lián)模型有很多數(shù)據(jù),這樣在創(chuàng)建模型時就成一場災難。例如,你創(chuàng)建用戶的年齡,它有著 1、2、3、4 …… 到 200 歲的下拉菜單選項。
您可以將這兩個模型的關系標記為 searchable
,此時不會顯示下拉菜單選項,而是顯示為一個可輸入的、漂亮的搜索欄。
要將關系模型中的下拉菜單變?yōu)?“搜索欄”,請在關聯(lián)模型的位置,添加方法 searchable()
:
BelongsTo::make('User')->searchable()
更多建議: