У меня есть связь между рабочими «днями» и проектами разного типа. Таким образом, моя запись «дни» дважды ссылается на мою таблицу «проекты», потому что у меня есть два разных типа проектов, называемых «Серия» и «Событие».
В моем ресурсе «дни» я создал два поля как таковых:
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 завершает фильтрацию обоих полей ресурсов.






Поскольку 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, которые фильтруют пользователей в зависимости от областей действия модели.
Я надеюсь, что это кому-то поможет, извините, если мой английский не так хорош.