# Основы
Поле HasMany предназначено для работы с одноименным отношением в Laravel и включает в себя все базовые методы.
Для создания данного поля используется статический метод make()
.
HasMany::make( Closure|string $label, ?string $relationName = null, Closure|string|null $formatted = null, ?ModelResource $resource = null)
$label
- лейбл, заголовок поля,$relationName
- название отношения,$resource
- ресурс модели на которую ссылается отношение.
Параметр $formatted
не используется в поле HasMany
!
Наличие ресурса модели, на которую ссылается отношение, обязательно!
Ресурс также необходимо
зарегистрировать
в сервис провайдере MoonShineServiceProvider в методе
menu()
или resources()
. Иначе, будет 404 ошибка.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', 'comments', resource: new CommentResource()) ];} //...
Если не указать $relationName
,
то название отношения будет определено автоматически на основе $label
.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ];} //...
Можно не указывать $resource
, если ресурс модели соответствует названию отношения.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', 'comments') ];} //...
# Поля
Метод fields()
позволят задать поля, которые будут отображаться в preview.
fields(Fields|Closure|array $fields)
use MoonShine\Fields\Relationships\BelongsTo;use MoonShine\Fields\Relationships\HasMany;use MoonShine\Fields\Text; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->fields([ BelongsTo::make('User'), Text::make('Text'), ]) ];} //...
# Создание объекта отношения
Метод creatable()
позволяет создавать новый объект отношения через модальное окно.
creatable( Closure|bool|null $condition = null, ?ActionButton $button = null,)
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->creatable() ];} //...
Кастомизировать кнопку создания можно передав методу параметр button.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->creatable( button: ActionButton::make('Custom button', '') ) ];} //...
# Количество записей
Метод limit()
позволяет ограничить количество записей отображаемых в preview.
limit(int $limit)
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->limit(1) ];} //...
# Только ссылка
Метод onlyLink()
позволят отобразить отношение в виде ссылки с количеством элементов.
onlyLink(?string $linkRelation = null, Closure|bool|null $condition = null)
Методу можно передать необязательные параметры:
linkRelation
- ссылка на отношение;-
condition
- замыкание или булево значение, отвечающее за отображение отношения как ссылки.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->onlyLink() ];} //...
Параметр linkRelation
позволяет создать ссылку на отношение с привязкой родительского ресурса.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->onlyLink('comment') ];} //...
Параметр condition
через замыкание позволят изменять способ отображения в зависимости от условий.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->onlyLink(condition: function (int $count, Field $field): bool { return $count > 10; }) ];} //...
# ID родителя
Если у связи есть ресурс, и необходимо получить ID родительского элемента, то можно воспользоваться трейтом ResourceWithParent.
use MoonShine\Resources\ModelResource;use MoonShine\Traits\Resource\ResourceWithParent; class PostImageResource extends ModelResource{ use ResourceWithParent; //...}
При использовании трейта, необходимо определить методы:
protected function getParentResourceClassName(): string{ return PostResource::class;} protected function getParentRelationName(): string{ return 'post';}
Для получения ID родителя используется метод getParentId()
.
$this->getParentId();
Рецепт: сохранение файлов в директории с ID родителя.
# Кнопка редактирования
Метод changeEditButton()
позволяет полностью переопределить кнопку редактирования.
use MoonShine\Fields\Relationships\HasMany; //... HasMany::make('Comments', 'comments', resource: new CommentResource()) ->changeEditButton( ActionButton::make( 'Edit', fn(Comment $comment) => (new CommentResource())->formPageUrl($comment) ) )
# Модальные окна
По умолчанию создание и редактирование записи поля HasMany происходит в модальном окне,
метод withoutModals()
позволяет отключить такое поведение.
use MoonShine\Fields\Relationships\HasMany; //... HasMany::make('Comments', 'comments', resource: new CommentResource()) ->withoutModals()
# Модификация
У поля HasMany существуют методы с помощью которых можно модифицировать кнопки, изменить TableBuilder для превью и формы, а также изменить onlyLink кнопку.
Метод modifyItemButtons()
позволяет изменить кнопки просмотра, редактирования,
удаления и массового удаления.
/** * @param Closure(ActionButton $detail, ActionButton $edit, ActionButton $delete, ActionButton $massDelete, self $field): array $callback */modifyItemButtons(Closure $callback)
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->modifyItemButtons( fn(ActionButton $detail, $edit, $delete, $massDelete, HasMany $ctx) => [$detail]) ) ];} //...
Метод modifyOnlyLinkButton()
позволяет изменить onlyLink кнопку.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->onlyLink() ->modifyOnlyLinkButton( fn(ActionButton $button, bool $preview) => $button ->when( $preview, fn(ActionButton $btn) => $btn->primary() fn(ActionButton $btn) => $btn->secondary() ) ) ];} //...
Методы modifyCreateButton()
и modifyEditButton()
позволяют изменять кнопки создания и редактирования.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->modifyCreateButton( fn(ActionButton $button) => $button->setLabel('Custom create button') ) ->modifyEditButton( fn(ActionButton $button) => $button->setLabel('Custom edit button') ) ->creatable(true) ];} //...
Метод modifyTable()
позволяет изменить TableBuilder для превью и формы.
use MoonShine\Fields\Relationships\HasMany; //... public function fields(): array{ return [ HasMany::make('Comments', resource: new CommentResource()) ->modifyTable( fn(TableBuilder $table, bool $preview) => $table ->when($preview, fn(TableBuilder $tbl) => $tbl->customAttributes(['style' => 'background: blue'])) ->unless($preview, fn(TableBuilder $tbl) => $tbl->customAttributes(['style' => 'background: green'])) ) ];} //...
# Продвинутое применение
Поле HasMany по умолчанию отображается вне основной формы ресурса.
Если необходимо отобразить поля отношения внутри основной формы,
то можно воспользоваться полем JSON в режиме asRelation()
.
//... public function fields(): array{ return [ Json::make('Comments', 'comments') ->asRelation(new CommentResource()) //... ]} //...
За более подробной информацией обратитесь к разделу поле Json .
Используя поле Template можно конструировать поле для отношений HasMany используя fluent interface в процессе объявления.
За более подробной информацией обратитесь к разделу поле Template .
В Moonshine можно кастомизировать страницу формы и разместить поля HasMany во вкладках используя декорации Tabs и Tab.
class PostFormPage extends FormPage{ public function components(): array { if(! $this->getResource()->getItemID()) { return parent::components(); } $bottomComponents = $this->getLayerComponents(Layer::BOTTOM); $imagesComponent = collect($bottomComponents)->filter(fn($component) => $component->getName() === 'images')->first(); $commentsComponent = collect($bottomComponents)->filter(fn($component) => $component->getName() === 'comments')->first(); $tabLayer = [ Block::make('', [ Tabs::make([ Tab::make('Edit', $this->mainLayer()), Tab::make('Images', [$imagesComponent]), Tab::make('Comments', [$commentsComponent]) ]) ]) ]; return [ ...$this->getLayerComponents(Layer::TOP), ...$tabLayer, ]; }}
За более подробно можно прочитать в статье Кастомизация страницы формы. MoonShine 2.0 .