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