【问题标题】:Laravel nova resource extending/overriding the create methodLaravel nova 资源扩展/覆盖 create 方法
【发布时间】:2019-02-22 15:58:38
【问题描述】:

我正在使用Laravel Nova 开发一个网络管理面板。

我遇到了一个问题,因为 Nova 是一项相当新的技术。

我现在想做的是添加隐藏字段或扩展或覆盖 create 方法。

这是我的场景。让我们保存一下,我有一个 vacancy nova 资源,其中包含以下字段。

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        Text::make('Title')->sortable(),
        Text::make('Salary')->sortable()
        // I will have another field, called created_by
    ];
}

非常简单。我喜欢做的是我想在数据库中添加一个名为created_by 的新字段。然后该字段将自动填充当前登录的用户id ($request->user()->id)。

如何覆盖或扩展 Nova 的 create 函数?我怎样才能实现它?

我可以使用资源事件,但是如何检索已登录的用户 活动?

【问题讨论】:

  • 这个方法的控制器类名是什么?
  • 没有控制器。我正在使用 Nova。nova.laravel.com/docs/1.0/installation.html
  • 我认为你可以像普通类一样重写它,但你需要指向这个重写这个方法的新类
  • 但我的想法是,这是一个很常见的情况,所以 Nova 必须有自己的方法。
  • Nova 资源有一个底层的 Eloquent 模型。我认为您可以在模型本身的 saving 事件中执行此操作。

标签: laravel laravel-nova


【解决方案1】:

您正在寻找的是Resource Events

来自文档:

所有 Nova 操作都使用你熟悉的典型的 save、delete、forceDelete、restore Eloquent 方法。因此,很容易监听 Nova 触发的模型事件并对其做出反应。 最简单的方法是简单地将模型观察者附加到模型:

如果你不想创建一个新的 observable,你也可以在你的 eloquent 模型中创建一个 boot 方法:

public static function boot()
{
    parent::boot();

    static::creating(function ($vacancy) {
        $vacancy->created_by = auth()->user()->id;
    });
}

但请注意,这些比 observables 更难跟踪,您或未来的下一个开发人员可能会摸不着头脑,想知道“created_at”属性是如何设置的。

【讨论】:

  • 我个人发现这种方法比在可观察对象中更容易“找到”,因为当我想了解模型行为时,我要做的第一件事就是转到模型定义。在我看来,这两种方法都很好、干净且可以接受……
【解决方案2】:

我认为你应该选择Observers。观察者将使您的代码更具可读性和可跟踪性。

以下是使用 Laravel Observers 实现相同目标的方法。

AppServiceProver.php

public function boot()
    {
        Nova::serving(function () {

            Post::observe(PostObserver::class);

        });
    }

PostObserver.php

public function creating(Post $post)
    {

        $post->created_by = Auth::user()->id;

    }

您可以简单地使用元数据破解 Nova 字段。

Text::make('created_by')->withMeta(['type' => 'hidden', 'value' => Auth::user()->id])

【讨论】:

    【解决方案3】:

    您也可以直接在 Nova 资源中执行此操作。每个 Nova 资源都有 newModel() 方法,当资源从 db 加载模型的新实例时调用该方法。您可以覆盖它并将设置任何默认值的逻辑放在那里(您应该始终检查值是否已经存在,并且仅在它们为空时设置,这只会在第一次创建模型时出现,这是你真正需要的):

    public static function newModel()
    {
        $model = static::$model;
        $instance = new $model;
    
        if ($instance->created_by == null) {
            $instance->created_by = auth()->user()->id;
        }
    
        return $instance;
    }
    

    【讨论】:

      【解决方案4】:

      a) 使用以下命令创建 Observer 类:

      php artisan make:observer -m "Post" PostObserver

      b) 在 PostObserver 中添加以下代码:

      $post->created_by = Auth::user()->id;

      c) 在 AppServiceProvider.php 中注册 PostObserver

      详解:https://medium.com/vineeth-vijayan/how-to-add-a-new-field-in-laravel-nova-resource-87f79427d38c

      【讨论】:

        【解决方案5】:

        从 Nova v3.0 开始,有一个原生的 Hidden 字段。

        用法:

        Hidden::make('Created By', 'created_by')
            ->default(
                function ($request) {
                    return $request->user()->id;
                }),
        

        文档:https://nova.laravel.com/docs/3.0/resources/fields.html#hidden-field

        【讨论】:

        • 这并不适用于所有人,因为您可能会提供属于“保存”事件的信息
        猜你喜欢
        • 2019-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-22
        • 1970-01-01
        • 2017-01-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多