RelatableQuery() для двух полей ресурсов в одной модели в Laravel Nova

У меня есть связь между рабочими «днями» и проектами разного типа. Таким образом, моя запись «дни» дважды ссылается на мою таблицу «проекты», потому что у меня есть два разных типа проектов, называемых «Серия» и «Событие».

В моем ресурсе «дни» я создал два поля как таковых:

BelongsTo::make('Series','series',Project::class)->sortable()->nullable(),
BelongsTo::make('Event','event',Project::class)->sortable()->nullable(),

Я пытаюсь отфильтровать проекты по их типам, поэтому я создал это:

public static function relatableProjects(NovaRequest $request, $query){
    return $query->where('type', 'Series');
}

Я пробовал создавать relatableSeries и relatableEvents, но они не работают. Как я могу правильно подключить это к полям, не создавая две отдельные таблицы для «серий» и «событий».

Приведенный выше relatableQuery завершает фильтрацию обоих полей ресурсов.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
2 040
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Поскольку relatableQuery() ссылается на relatableModel() (поэтому relatableProjects() ссылается на модель Project), я смог создать еще одну модель исключительно для того, чтобы помочь с этим.

Я создал модель Event, которая ссылается на ту же таблицу projects, а затем смог создать метод relatableEvents() для использования запроса фильтра where().

Примечание: Мне также пришлось создать ресурс Event, который ссылается на модель Event, поскольку именно так работает Nova, но я смог скрыть его от доступа, о чем вы можете найти дополнительную информацию о здесь.

См. измененные поля BelongsTo и новую модель ниже:

Дневной ресурс

    /**
     * Build a "relatable" query for the given resource.
     *
     * This query determines which instances of the model may be attached to other resources.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function relatableProjects(NovaRequest $request, $query){
        return $query->where('type', 'Series');
    }

    /**
     * Build a "relatable" query for the given resource.
     *
     * This query determines which instances of the model may be attached to other resources.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function relatableEvents(NovaRequest $request, $query){
        return $query->where('type', 'Event');
    }

    /**
     * Get the fields displayed by the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function fields(Request $request)
    {
        return [
            ID::make()->hideFromIndex()->hideFromDetail()->hideWhenUpdating(),
            BelongsTo::make('User','user',User::class)->sortable(),
            BelongsTo::make('Budget','budget',Budget::class)->sortable()->nullable(),
            BelongsTo::make('Series','series',Project::class)->sortable()->nullable(),
            BelongsTo::make('Event','event',Event::class)->sortable()->nullable(),
            DateTime::make('Last Updated','updated_at')->hideFromIndex()->readOnly(),
            new Panel('Schedule',$this->schedule()),
            new Panel('Time Entry',$this->timeEntries()),

        ];
    }

Модель событий

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Event extends Model
{
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'projects';

    protected $casts = [
        'starts_on' => 'date',
        'ends_on' => 'date',
    ];

    public function event(){
        return $this->belongsTo('App\Event');
    }

    public function project(){
        return $this->belongsTo('App\Project');
    }
}

я знаю, что это старый вопрос, но я столкнулся с той же проблемой с полем laravel nova, принадлежащим к пользователям, в каком-то ресурсе у меня есть принадлежность, которая относится к пользователям, но они должны иметь роль «супервайзера» в другом ресурсе, у меня есть поле принадлежности, относящееся к пользователям но они должны иметь роль «охранника», так как поле laravel nova ownto просто принимает всех пользователей в обоих случаях, когда все пользователи появляются, и кажется, что у поля nova ownto нет способа, или, по крайней мере, я не нашел его для охвата запроса, так что я сделал, это создал класс php с именем BelongstoScoped, этот класс расширяет поле laravel nova BelongsTo, поэтому я перезаписал метод, ответственный за создание запроса

<?php

namespace App\Nova\Customized;

use Laravel\Nova\Query\Builder;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Http\Requests\NovaRequest;

class BelongsToScoped extends BelongsTo
{

    private  $modelScopes = [];

    //original function in laravel belongsto field
    public function buildAssociatableQuery(NovaRequest $request, $withTrashed = false)
    {
        $model = forward_static_call(
            [$resourceClass = $this->resourceClass, 'newModel']
        );

        $query = new Builder($resourceClass);
        
        //here i chaned this:
        /*
        $query->search(
                                $request,  $model->newQuery(), $request->search,
                                [], [], ''
                          );
        */
        //To this:
        /*
        $query->search(
                                $request,  $this->addScopesToQuery($model->newQuery()), $request->search,
                                [], [], ''
                          );
        */
        //The method search receives a query builder as second parameter, i just passed the result of custom function 
        //addScopesToQuery as second parameter, thi method returns the same query but with the model scopes passed

        $request->first === 'true'
                        ? $query->whereKey($model->newQueryWithoutScopes(), $request->current)
                        : $query->search(
                                $request,  $this->addScopesToQuery($model->newQuery()), $request->search,
                                [], [], ''
                          );

        return $query->tap(function ($query) use ($request, $model) {
            forward_static_call($this->associatableQueryCallable($request, $model), $request, $query, $this);
        });
    }

    //this method reads the property $modelScopes and adds them to the query
    private function addScopesToQuery($query){
        foreach($this->modelScopes as $scope){
            $query->$scope();
        }
        return $query;
    }

    // this method should be chained tho the field 
    //example: BelongsToScoped::make('Supervisores', 'supervisor', 'App\Nova\Users')->scopes(['supervisor', 'active'])
    public function scopes(Array $modelScopes){

        $this->modelScopes = $modelScopes;
        return $this;

    }

}

?>

В моей модели пользователей у меня есть области для супервизоров и ролей охраны, например:

public function scopeActive($query)
    {
        return $query->where('state', 1);
    }

    public function scopeSupervisor($query)
    {
        return $query->role('supervisor');
    }

    public function scopeSuperadmin($query)
    {
        return $query->role('superadmin');
    }

    public function scopeGuarda($query)
    {
        return $query->role('guarda');
    }

Итак, в ресурсе laravel nova я просто включил использование этого класса * помните, что пространство имен зависит от того, как вы назовете свой файл, в моем случае я создал папку Customized и включил туда файл:

use App\Nova\Customized\BelongsToScoped;

В полях в ресурсе nova я использовал вот так:

BelongsToScoped::make('Supervisor', 'supervisorUser', 'App\Nova\Users\User')
                            ->scopes(['supervisor', 'active'])
                            ->searchable()

Таким образом, я мог бы вызвать поле принадлежности в ресурсах nova, которые фильтруют пользователей в зависимости от областей действия модели.

Я надеюсь, что это кому-то поможет, извините, если мой английский не так хорош.

Другие вопросы по теме