在 Nova Action fields() 上运行 where()->get()

问题描述 投票:0回答:5

我正在尝试提供一个

Select
列表,其中仅包含通过数据透视表与模型相关的记录。

在为客户构建时间跟踪器/预算软件时,我正在使用两个模型,称为预算和项目,它们通过数据透视表连接在一起。 (所以

budgets
projects
budget_project

我正在尝试在

Budget
字段上显示与所选
Budget
(调用操作时来自
Select
资源)相关的所有项目。我不知道如何将
model->id
传递到 fields 函数中。然后,我将运行一些代码来分析与给定
Projects
关联的
Budget
并创建一堆跨越日期范围和其他关系的记录。

请帮忙!

我正在寻找这样的东西......

class CreateSchedule extends Action
{
    use InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Perform the action on the given models.
     *
     * @param  \Laravel\Nova\Fields\ActionFields  $fields
     * @param  \Illuminate\Support\Collection  $models
     * @return mixed
     */
    public function handle(ActionFields $fields, Collection $models)
    {
        return Action::message('all good');
    }

    /**
     * Get the fields available on the action.
     *
     * @return array
     */
    public function fields()
    {
        $budgetProject = BudgetProject::where('budget_id',$this->id)->get();

        foreach($budgetProject as $bp){
            $projectArray[$bp->project_id] = $bp->project->name;
        }

        return [
            Select::make('Project','project_id')->options($projectArray),
        ];
    }
}
php laravel crud laravel-nova
5个回答
4
投票

对我来说它是这样工作的

在Resource类中传递id

 (new LogsDiffAction($this->id))

在Action类中创建一个构造函数来接收这个参数

 protected $model;

public function __construct($model)
{
    $this->model = $model;
}

在你可以做的领域

if ($this->model) {
        $entity = Activity::find($this->model);
        $model = json_decode($entity->properties, true);
        $partial = view('admin.nova.log-diff-partial', ['model' => $model])->toHtml();

        return [
            Heading::make($partial)->asHtml(),
        ];
    }

2
投票

当我在时事通讯部分工作时,我遇到了类似的问题,我有

Template
Campaign
模型

如果您想获取记录的数据,您可以通过这样做添加您的模型 注意 onlyOneTabeRow 函数是一个内联操作,并且必须传递模型

public function actions(Request $request)
{
    return [
        (new CreateCampaign($this))
            ->onlyOnTableRow()
    ];
}

现在您可以在 CreateCampaign 行动承包商中收到它们

public function __construct($model)
{
    $this->template = $model;
}

无需向数据库发出任何请求,您就可以像这样获取当前记录数据

public function fields()
{
    return [
        Text::make('Name', 'name')
            ->default(function ($request) {
                return $this->template->name;
            })
            ->rules('required'),
        Text::make('Subject', 'subject')
            ->default(function ($request) {
                return $this->template->subject;
            })->rules('required'),
        Textarea::make('Content', 'content')
            ->default(function ($request) {
                return $this->template->content;
            })->rules('required')->showOnIndex(),
        Hidden::make('Template Id', 'template_id')
            ->default(function ($request) {
                return $this->template->id;
            })
    ];
}

这是我在第一条记录中单击内联操作

Create Campaign
后想要的照片,我得到一个表单,其中包含我想要在操作表单中显示的特定记录


0
投票

对于那些与 Nova 斗争的人,我必须做一些非常类似的事情。 正如其他人所建议的,您需要执行以下步骤。

  1. 在注册操作时,将 Action 类中所需的任何内容作为参数传递。
    ( new MyAction($this->myParam) )
  2. 在操作类中创建一个构造函数并接受参数。
protected $receivedParam;

public function __construct($param)
{
   $this->receivedParam = $param;
}

然后,您可以在 fields() 中使用您的参数来执行您需要执行的任何操作。

从 Lens 发起的操作注意事项

但是,当从镜头启动操作时,这将不起作用,因为您在执行

( new MyAction($this->someParam) )
时不会简单地获取参数。在 Lens 的上下文中,您需要首先击败弹出的 Std 对象,然后您需要从 $this 中挖掘资源及其属性。

// pass entire $this here and filter down in the Action Class
return [(new GiveMediaAccountAccessViaLens($this))]; // registering action from Lens
// Action Class
    protected $receivedParam;

    public function __construct($receivedParam)
    {
        $this->receivedParam = $receivedParam; // $receivedParam is $this from MediaAccountFilterByClient Lens
    }


    public function fields()
    {
        if(!$this->receivedParam->resource instanceof Model)
        {
            // If you are trying to generate a dropdown/select then you should set your options to
            // empty array. $options = [];
            $options = [];
        }
        else
        {
            // Here, $this->receivedParam->resource contains the Model Object, by calling
            // getRawOriginal() on it, You will get the Original Attributes array which contains
            // key value pair, like "some Attribute => "value"
            // $this->receivedParam->resource->getRawOriginal()['someAttributeOnModel']
            
            // Finally in case you are making a dropdown, you can your data to the array that
            // will be passed to Select field.
            $options = Arr::add($options, "value", "label");
            
        }

        // finally return the fields with custom filled Dropdown
        return [
            // key will be used as key to get the field value in handle()
            Select::make('Label', 'key')->options($options),
        ];
    }

对于我的用例,我最终使用了两个操作类(一个在从 Lens 注册操作时使用,另一个用于从资源类注册操作,因为我正在生成自定义下拉列表。 Nova 做了一些奇怪的事情,我在从资源执行操作时得到了 foreach 的无效参数。


0
投票

对于 Nova 4(可能还有以前的版本),为了获得完整的功能,需要一些额外的东西来对抗 Nova 尝试在调用

handle()
时重新检查应包含哪些字段。

根据 Mohamed 的出色回答,您需要通过

actions
字段传递模型:

public function actions(Request $request)
{
    return [
        (new YourAction($this->model()))->showOnTableRow()
    ];
}

并且您必须修改您的 Action 类(这是我的项目之一的示例):

protected $model;

public function __construct($model) {
    $this->model = $model;
}

public function handle(ActionFields $fields, Collection $models)
{
    $model = $fields->model;
    $brand = $fields->brand;
    $mould = $fields->mould;
    // do stuff
}

public function fields(NovaRequest $request)
{
    if ($this->model && $this->model->id) {
        return [
            Hidden::make('Supplier')
                ->readonly()
                ->default(fn($request) => $this->model->supplier_id),
            Text::make('Brand')
                ->default(fn($request) => $this->model->brand ?? '')
                ->readonly(),
            Text::make('Mould')
                ->default(fn($request) => $this->model->mould ?? '')
                ->readonly(),
            Text::make('Model')->required(),
        ];
    }
    // We are just being called to check what fields should be included.
    return [
        Text::make('Model')
            ->required(),
        Text::make('Brand')
            ->required(),
        Text::make('Mould')
            ->required(),
    ];
}

-1
投票
public function fields(Request $request)
{
    $budgetProject = BudgetProject::where('budget_id',$request->budget_id)->get();

    dd($budgetProject);

    foreach($budgetProject as $bp){
        $projectArray[$bp->project_id] = $bp->project->name;
    }

    return [
        Select::make('Project','project_id')->options($projectArray),
    ];
}
© www.soinside.com 2019 - 2024. All rights reserved.