简体   繁体   English

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

[英]Run where()->get() on Nova Action fields()

I'm trying to provide a Select list with only records that are related to the model via a pivot table.我正在尝试提供一个Select列表,其中仅包含通过数据透视表与模型相关的记录。

While building a time tracker/budgeting software for a client I have two models I'm working with called Budgets and Projects that are joined together with a pivot table.在为客户构建时间跟踪器/预算软件时,我正在使用两个模型,称为预算和项目,它们与数据透视表连接在一起。 (So budgets , projects , and budget_project ) (所以, budgetsprojectsbudget_project

I'm trying to display all projects that are related to a selected Budget (from the Budget resource when calling an action) on a Select field.我正在尝试在Select字段上显示与所选Budget (从调用操作时的Budget资源)相关的所有项目。 I can't figure out how to pass the model->id into the fields function.我不知道如何将model->id传递给 fields 函数。 I will then be running some code to analyze the Projects associated with the given Budget and creating a bunch of records that extend across the date range and other relationships.然后,我将运行一些代码来分析与给定Budget相关的Projects ,并创建一系列跨越日期范围和其他关系的记录。

Please help!请帮忙!

I'm looking for something like this...我正在寻找这样的东西......

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

For me it it works like this对我来说它是这样工作的

pass the id in the Resource class在 Resource 类中传递 id

 (new LogsDiffAction($this->id))

Create a constructor in Action class to receive this parameter在 Action 类中创建一个构造函数来接收这个参数

 protected $model;

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

and in fields you can do在你可以做的领域

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

I face a similar issue when I was working in the newsletter section where I have Template and Campaign models当我在拥有TemplateCampaign模型的时事通讯部分工作时,我遇到了类似的问题

You can add your model by doing this if you want to get recorded data Notice onlyOneTabeRow function is an inline action and it's Mandatory to pass model如果你想获得记录的数据,你可以通过这样做来添加你的模型 注意 onlyOneTabeRow 函数是一个内联动作,必须传递模型

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

Now you can receive them in CreateCampaign action contractor现在您可以在 CreateCampaign 行动承包商中接收它们

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

And without making any request to the database you can get current record data like this无需向数据库发出任何请求,您就可以获得这样的当前记录数据

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

Here is a photo of what I want once I clicked on inline action Create Campaign in the first record I get a form with the specific record I want displaying in action form这是我在第一条记录中单击内联操作Create Campaign后我想要的照片 我得到一个表单,其中包含我想要在操作表单中显示的特定记录

laravel nova 内联动作

For anyone who will struggle with Nova, I had to do something very similar.对于任何将与 Nova 斗争的人,我必须做一些非常相似的事情。 Just as other have suggested, You need to do the following steps.正如其他人所建议的那样,您需要执行以下步骤。

  1. Pass whatever you need in the Action class as parameter while registering action.在注册动作时,将 Action 类中需要的任何内容作为参数传递。 ( new MyAction($this->myParam) )
  2. Make a constructor in your action class and accept the parameter.在您的操作类中创建一个构造函数并接受参数。
protected $receivedParam;

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

You can then use your parameter in your fields() to do whatever you need to do with it.然后你可以在你的 fields() 中使用你的参数来做任何你需要做的事情。

Note For Actions initiated From Lens从 Lens 发起的操作的注意事项

However, While initiating Action from Lens, this will not work as you won't simply get the parameter while doing ( new MyAction($this->someParam) ) .但是,当从 Lens 启动 Action 时,这将不起作用,因为您在执行( new MyAction($this->someParam) )时不会简单地获取参数。 In the context of Lens, You need to first beat the Std Object that pops up and then you need to dig down the resource and then its attributes from $this.在 Lens 的上下文中,您需要首先击败弹出的 Std Object,然后您需要从 $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),
        ];
    }

For my use case, I ended up using two Action Classes (one to use while registering action from Lens, another one for Action registration from Resource Class because I was generating a custom dropdown. Nova does some weird stuff and I was getting an invalid argument for foreach while executing action from Resource.对于我的用例,我最终使用了两个动​​作类(一个在从 Lens 注册动作时使用,另一个用于从资源类注册动作,因为我生成了一个自定义下拉列表。Nova 做了一些奇怪的事情,我得到了一个无效的参数在从 Resource 执行操作时为 foreach。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM