Laravel Nova 模型關(guān)聯(lián)

2023-02-16 17:08 更新

除了我們之前討論過的那些字段,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')

標(biāo)題屬性

當(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í)行它。

標(biāo)題屬性

當(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;
}

遠(yuǎn)層一對多

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')

多態(tài)關(guān)聯(lián)

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)。

多對多的多態(tài)關(guān)聯(lián)

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'),
        ];
    }
}

標(biāo)題屬性

當(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;
}

關(guān)聯(lián)搜索

在我們使用 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()


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號