模型关联

未匹配的标注

除了我们之前讨论过的那些字段,Nova 还支持 Laravel 模型的关联关系。只要给资源添加一个关联关系,你就能体会到 Nova 的强大之处,因为你可以在资源详情页快速的查看并搜索该资源的关联模型:

Detail Screen Relationship

一对一

这个 HasOne 对应一个 hasOne Eloquent 关系。例如,让我们假设一个 User 模型 hasOne Address 模型。我们可以将这种关系添加到我们的 User Nova 资源中,如下所示:

use Laravel\Nova\Fields\HasOne;

HasOne::make('Address')

就像其他类型的字段一样,关系字段将自动地 “snake case” 字段的显示名称,来确定底层关系的方法或属性。然而,你可以将它作为第二个参数传递给这个字段的 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')

标题属性

当创建或编辑包含 BelongsTo 字段的资源时,下拉框或搜索框里会显示该资源的「标题」。假如 User 资源的标题是 name 属性,那么 BelongsTo 选择菜单里显示的就是他的 name

Belongs To Title

如果要自定义资源的「titile」,可以在资源类里定义一个 title 属性:

public static $title = 'name';

此外,你也可以覆盖资源的 title 方法:

/**
 * 获取资源显示的值。
 *
 * @return string
 */
public function title()
{
    return $this->name;
}

多对多

BelongsToMany 字段对应于模型的 belongsToMany 关联. 例如, 我们假定有一个 User 模型 belongsToMany Role 模型. 我们就可以像这样将它添加到 User Nova 资源中:

use Laravel\Nova\Fields\BelongsToMany;

BelongsToMany::make('Roles')

主字段

如果你的 belongsToMany 关联中间表还存着其他的关联字段 , 你也可以将它附到 BelongsToMany Nova 关联字段上. 一旦这些字段被附到该关联, 那他们将会在关联资源列表中展示.

例如,我们假定我们的 User 模型 belongsToMany Role 模型. 在 role_user 中间表, 让我们想象一下 notes字段包含一些关联关系中简单的文本 我们可以使用 fields 方法把这个字段附加到 BelongsToMany 字段上:

BelongsToMany::make('Roles')
    ->fields(function () {
        return [
            Text::make('Notes'),
        ];
    });

当然, 这也可以在定义相反关联时使用. 所以, 如果我们在 User 资源中定义了一个BelongsToMany 字段 , 我们也可以在 Role 资源中定义反向关联:

BelongsToMany::make('Users')
    ->fields(function () {
        return [
            Text::make('Notes'),
        ];
    });

在两处分别定义这样的关联可能会让我们的代码重复, Nova 允许你通过传入一个可调用的对象给 fields 方法:

BelongsToMany::make('Users')->fields(new RoleUserFields)

上面的例子中, RoleUserFields 类可以只有一个 __invoke 方法, 并返回一个包含附加字段的数组:

<?php

namespace App\Nova;

use Laravel\Nova\Fields\Text;

class RoleUserFields
{
    /**
     *  获取关联模型的附加字段
     *
     * @return array
     */
    public function __invoke()
    {
        return [
            Text::make('Notes'),
        ];
    }
}

主操作

通常, Nova actions 是基于资源操作的。 然而, 你也可以把 actions 绑定到 belongsToMany 字段 然后他们就可以在 pivot / 中间表记录上操作了。为了实现它,你可以在字段定义时使用 actions 链式方法:

BelongsToMany::make('Roles')
    ->actions(function () {
        return [
            new Actions\MarkAsActive,
        ];
    });

一旦 action 被绑定到这个字段,你就可以从父级资源屏幕上的关系索引中选择这个 action 并且执行它。

Actions

了解更多关于 Nova actions, 查看完成文档 action documentation.

标题属性

BelongsToMany 字段出现在资源创建和更新操作时,一个下拉选择菜单或搜索框会显示当前资源的 “title” 。例如: Role 资源可以使用 name 属性作为其标题。然后,当资源显示在 BelongsToMany 选择菜单时,这个属性也会显示。

Belongs To Many Title

为了自定义这个资源的 “title” ,你可以在类内定义一个 title 成员属性:

public static $title = 'name';

另外,你可以复写资源的 title 方法:

/**
 * 获取资源需要被显示的值
 * @return string
 */
public function title()
{
    return $this->name;
}

远层一对多

MorphMany 字段响应 morphMany Eloquent 关联。例如:我们假设
PostComment 模型存在一对多的多态关联。我们可以为 Post Nova 资源添加关联,如下:

use Laravel\Nova\Fields\MorphMany;

MorphMany::make('Comments')

多态关联

MorphTo 字段对应于 morphTo Eloquent关系。 例如,让我们假设一个Comment 模型与 PostVideo 模型都有多态关系。 我们可以将这种关系添加到我们的 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 字段可以与哪些类型的资源相关联。 Nova 将使用此信息在创建和更新显示 MorphTo 字段的类型选择菜单:

Morph To Type

多态标题属性

当在资源创建/更新显示 MorphTo 字段时,将自动显示可用资源的[标题属性](#title-attributes)。

多对多的多态关联

MorphToMany 字段对应于 morphToMany Eloquent 关系。例如,让我们假设一个 Post 模型与 Tag 模型有多对多多态关系。 我们可以将这种关系添加到我们的 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 资源中定义它的反向关联:

MorphToMany::make('Posts')
    ->fields(function () {
        return [
            Text::make('Notes'),
        ];
    });

由于在关系的两端定义字段会导致一些代码重复,nova允许您将可调用对象传递给“fields”方法:

MorphToMany::make('Users')->fields(new TaggableFields)

在这个例子中,’taggablefields’类是一个返回数组的核心字段的简单、可调用的类,

<?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字段显示在资源创建/更新页面上时,下拉选择菜单或搜索菜单将显示资源的“标题”。例如,Tag资源可以使用name属性作为它的标题。然后,当资源在MorphToMany选择菜单中显示时,该属性将显示:

Morph To Many Title

您可以在资源类上定义一个 title 属性, 自定义资源的 title 属性值:

public static $title = 'name';

或者你可以重写资源的title方法:

/**
 * 获取资源类显示的标题。
 *
 * @return string
 */
public function title()
{
    return $this->name;
}

关联搜索

在我们使用 BelongsTo、BelongsToMany、MorphTo、MorphToMany 来建立两个模型的关联关系时,Nova 会默认显示一个简单的下拉选择栏。但是,当我们两个关联模型有很多数据,这样在创建模型时就成一场灾难。例如,你创建用户的年龄,它有着 1、2、3、4 …… 到 200 岁的下拉菜单选项。

您可以将这两个模型的关系标记为 searchable,此时不会显示下拉菜单选项,而是显示为一个可输入的、漂亮的搜索栏。

Belongs To Search

要将关系模型中的下拉菜单变为“搜索栏”,请在关联模型的位置,添加方法searchable()

BelongsTo::make('User')->searchable()

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/nova/1.0/model-...

译文地址:https://learnku.com/docs/nova/1.0/model-...

上一篇 下一篇
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
贡献者:13
讨论数量: 0
发起讨论 只看当前版本


暂无话题~