- Basics
- Fields
- Creating a relationship object
- Record count
- Only link
- Parent ID
- Edit button
- Modal window
- Modification
- Adding ActionButtons
- Advanced usage
Basics
The HasMany field is designed to work with the relationship of the same name in Laravel and includes all Basic methods.
To create this field, use the static method make()
.
HasMany::make( Closure|string $label, ?string $relationName = null, Closure|string|null $formatted = null, ModelResource|string|null $resource = null,)
-
$label
- label, header of the field, -
$relationName
- name of the relation, -
$resource
- model resource that the relation points to.
The $formatted
parameter is not used in the HasMany
field!
The existence of the model resource that the relationship points to is mandatory.
The resource also needs to be registered in the MoonShineServiceProvider
service provider in the $core->resources()
method. Otherwise, a 500 error will occur (Resource is required for MoonShine\Laravel\Fields\Relationships\HasMany...).
use MoonShine\Laravel\Fields\Relationships\HasMany; HasMany::make('Comments', 'comments', resource: CommentResource::class)
You can omit the $resource
if the model resource matches the name of the relation.
class CommentResource extends ModelResource{ //...}//...HasMany::make('Comments', 'comments')
If you do not specify $relationName
, then the name of the relation will be determined automatically based on $label
(following camelCase rules).
class CommentResource extends ModelResource{ //...}//...HasMany::make('Comments')
Fields
The fields()
method allows you to set the fields that will be displayed in the preview.
fields(FieldsContract|Closure|iterable $fields)
use MoonShine\Laravel\Fields\Relationships\BelongsTo;use MoonShine\Laravel\Fields\Relationships\HasMany;use MoonShine\UI\Fields\Text; HasMany::make('Comments', resource: CommentResource::class) ->fields([ BelongsTo::make('User'), Text::make('Text'), ])
Creating a relationship object
The creatable()
method allows you to create a new relationship object through a modal window.
creatable( Closure|bool|null $condition = null, ?ActionButtonContract $button = null,)
HasMany::make('Comments', resource: CommentResource::class) ->creatable()
You can customize the create button by passing the button parameter in the method.
HasMany::make('Comments', resource: CommentResource::class) ->creatable( button: ActionButton::make('Custom button', '') )
Record count
The limit()
method allows you to limit the number of records displayed in the preview.
limit(int $limit)
HasMany::make('Comments', resource: CommentResource::class) ->limit(1)
Only link
The relatedLink()
method allows you to display the relationship as a link with the count of elements. The link will lead to the IndexPage of the child resource from the HasMany relationship, only showing those data elements.
relatedLink(?string $linkRelation = null, Closure|bool $condition = null)
You can pass optional parameters to the method:
-
linkRelation
- link to the relation, -
condition
- closure or boolean value responsible for displaying the relation as a link.
Don’t forget to add the relation to the with property of the resource.
HasMany::make('Comments', resource: CommentResource::class) ->relatedLink()
The linkRelation
parameter allows you to create a link to the relation with parent resource binding.
HasMany::make('Comments', resource: CommentResource::class) ->relatedLink('comment')
The condition
parameter through a closure allows you to change the display method based on conditions.
HasMany::make('Comments', resource: CommentResource::class) ->relatedLink(condition: function (int $count, Field $field): bool { return $count > 10; })
Parent ID
If the relation has a resource, and you want to get the ID of the parent element, you can use the ResourceWithParent trait.
use MoonShine\Resources\ModelResource;use MoonShine\Traits\Resource\ResourceWithParent; class PostImageResource extends ModelResource{ use ResourceWithParent; //...}
When using the trait, you need to define the methods:
protected function getParentResourceClassName(): string{ return PostResource::class;} protected function getParentRelationName(): string{ return 'post';}
To get the parent ID, use the getParentId()
method.
$this->getParentId();
Recipe: saving files of HasMany relations in the directory with the parent ID.
Edit button
The changeEditButton()
method allows you to completely override the edit button.
HasMany::make('Comments', 'comments', resource: CommentResource::class) ->changeEditButton( ActionButton::make( 'Edit', fn(Comment $comment) => app(CommentResource::class)->formPageUrl($comment) ) )
Modal window
By default, creating and editing a record in the HasMany field occurs in a modal window; the withoutModals()
method allows you to disable this behavior.
HasMany::make('Comments', 'comments', resource: CommentResource::class) ->withoutModals()
Modification
The HasMany field has methods that can be used to modify buttons, change the TableBuilder for preview and form, as well as change the relatedLink button.
searchable()
By default, a search field is available on the form page for the HasMany field; to disable it, you can use the searchable
method.
public function searchable(Closure|bool|null $condition = null): static
HasMany::make('Comments', 'comments', resource: CommentResource::class) ->searchable(false) // disables the search field
modifyItemButtons()
The modifyItemButtons()
method allows you to change the view, edit, delete, and mass delete buttons.
/** * @param Closure(ActionButtonContract $detail, ActionButtonContract $edit, ActionButtonContract $delete, ActionButtonContract $massDelete, static $ctx): array $callback */modifyItemButtons(Closure $callback)
HasMany::make('Comments', resource: CommentResource::class) ->modifyItemButtons( fn(ActionButton $detail, $edit, $delete, $massDelete, HasMany $ctx) => [$detail] )
modifyRelatedLink()
The modifyRelatedLink()
method allows you to change the relatedLink button.
HasMany::make('Comments', resource: CommentResource::class) ->relatedLink() ->modifyRelatedLink( fn(ActionButton $button, bool $preview) => $button ->when($preview, fn(ActionButton $btn) => $btn->primary()) ->unless($preview, fn(ActionButton $btn) => $btn->secondary()) )
modifyCreateButton() / modifyEditButton()
The modifyCreateButton()
and modifyEditButton()
methods allow you to change the create and edit buttons.
HasMany::make('Comments', resource: CommentResource::class) ->modifyCreateButton( fn(ActionButton $button) => $button->setLabel('Custom create button') ) ->modifyEditButton( fn(ActionButton $button) => $button->setLabel('Custom edit button') ) ->creatable(true)
modifyTable()
The modifyTable()
method allows you to change the TableBuilder for preview and form.
HasMany::make('Comments', resource: CommentResource::class) ->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'])) )
Redirect after modification
The redirectAfter()
method allows for redirection after saving/adding/deleting.
HasMany::make('Comments', resource: CommentResource::class) ->redirectAfter(fn(int $parentId) => route('home'))
Modify QueryBuilder
The modifyBuilder()
method allows you to modify the query through QueryBuilder.
HasMany::make('Comments', resource: CommentResource::class) ->modifyBuilder(fn(Relation $query, HasMany $ctx) => $query)
Adding ActionButtons
indexButtons()
The indexButtons
method allows you to add additional ActionButtons for working with HasMany elements.
HasMany::make('Comments', 'comments', resource: CommentResource::class) ->indexButtons([ ActionButton::make('Custom button') ])
formButtons()
The formButtons
method allows you to add additional ActionButtons inside the form when creating or editing a HasMany element.
HasMany::make('Comments', 'comments', resource: CommentResource::class) ->formButtons([ ActionButton::make('Custom form button') ])
Advanced usage
Relation through JSON field
The HasMany field is displayed outside the main resource form by default. If you need to display the relation fields inside the main form, you can use the JSON field in asRelation()
mode.
Json::make('Comments', 'comments') ->asRelation(CommentResource::class) //...
Relation through Template field
Using the Template field, you can build a field for HasMany relationships using a fluent interface during declaration.
For more detailed information, refer to the Template field.