ModelResource расширяет CrudResource и предоставляет функциональность для работы с моделями Eloquent.
Он обеспечивает основу для создания ресурсов, связанных с моделями базы данных.
ModelResource предоставляет методы для выполнения CRUD-операций, управления отношениями, применения фильтров и многое другое.
Вы также можете ознакомиться с разделом CrudResource.
CrudResource - это абстрактный класс предоставляющий базовый интерфейс для CRUD операций без привязки к хранилищу и типу данных.
Под капотом, ModelResource расширяет CrudResource и сразу включает возможность работы с Eloquent.
Если углубляться в детали MoonShine, то вы увидите все те же стандартные Controller, Model и Blade views.
Если бы вы разрабатывали самостоятельно, то создать ресурс контроллеры и ресурс маршруты можно следующим образом:
php artisan make:controller Controller --resource
php artisan make:controller Controller --resource
php artisan make:controller Controller --resource
php artisan make:controller Controller --resource
php artisan make:controller Controller --resource
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
namespaces
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
namespaces
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
Но эту работу можно поручить админ-панели MoonShine, которая будет их генерировать и объявлять самостоятельно.
ModelResource является основным компонентом для создания раздела в админ-панели при работе с базой данных.
php artisan moonshine:resource Post
php artisan moonshine:resource Post
php artisan moonshine:resource Post
php artisan moonshine:resource Post
php artisan moonshine:resource Post
Для более подробной информации обратитесь к разделу Команды.
Базовые параметры, которые можно менять у ресурса, чтобы кастомизировать его работу.
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected string $model = Post::class;
protected string $title = 'Posts';
protected array $with = ['category'];
protected string $column = 'id';
}
namespaces
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
/**
* @extends ModelResource<Post>
*/
class PostResource extends ModelResource
{
// Модель
protected string $model = Post::class;
// Заголовок раздела
protected string $title = 'Posts';
// Eager load
protected array $with = ['category'];
// Поле для отображения значений в связях и хлебных крошках
protected string $column = 'id';
// ...
}
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
/**
* @extends ModelResource<Post>
*/
class PostResource extends ModelResource
{
// Модель
protected string $model = Post::class;
// Заголовок раздела
protected string $title = 'Posts';
// Eager load
protected array $with = ['category'];
// Поле для отображения значений в связях и хлебных крошках
protected string $column = 'id';
// ...
}
namespaces
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
/**
* @extends ModelResource<Post>
*/
class PostResource extends ModelResource
{
// Модель
protected string $model = Post::class;
// Заголовок раздела
protected string $title = 'Posts';
// Eager load
protected array $with = ['category'];
// Поле для отображения значений в связях и хлебных крошках
protected string $column = 'id';
// ...
}
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
/**
* @extends ModelResource<Post>
*/
class PostResource extends ModelResource
{
// Модель
protected string $model = Post::class;
// Заголовок раздела
protected string $title = 'Posts';
// Eager load
protected array $with = ['category'];
// Поле для отображения значений в связях и хлебных крошках
protected string $column = 'id';
// ...
}

Ресурс автоматически регистрируется в MoonShineServiceProvider при вызове команды php artisan moonshine:resource.
Но если вы создаете раздел вручную, то вам необходимо самостоятельно его объявить в системе в MoonShineServiceProvider.
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
])
->pages([
...$config->getPages(),
])
;
}
}
namespaces
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
/**
* @param MoonShine $core
* @param MoonShineConfigurator $config
*
*/
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
// ...
])
->pages([
...$config->getPages(),
])
;
}
}
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
/**
* @param MoonShine $core
* @param MoonShineConfigurator $config
*
*/
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
// ...
])
->pages([
...$config->getPages(),
])
;
}
}
namespaces
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
/**
* @param MoonShine $core
* @param MoonShineConfigurator $config
*
*/
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
// ...
])
->pages([
...$config->getPages(),
])
;
}
}
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
/**
* @param MoonShine $core
* @param MoonShineConfigurator $config
*
*/
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
// ...
])
->pages([
...$config->getPages(),
])
;
}
}
В MoonShine также доступна автозагрузка страниц и ресурсов.
Она выключена по-умолчанию и для активации нужно вызвать метод autoload() в MoonShineServiceProvider вместо указания ссылок на страницы и ресурсы.
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
namespaces
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
namespaces
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
При деплое проекта на продакшен в Laravel 11+ рекомендуется вызывать консольную команду php artisan optimize.
Помимо её основных функций, она также выполнит кэширование ресурсов MoonShine.
При использовании Laravel 10 необходимо вручную вызывать консольную команду php artisan moonshine:optimize для оптимизации процесса инициализации админ панели.
Очистить кэш панели можно как командой php artisan optimize:clear в Laravel 11,
так и прямым вызовом консольной команды php artisan moonshine:optimize-clear.
Если после создания классов приложение их не видит - обновите кэш композера командой composer dump-autoload.
По умолчанию записи в таблице ресурса сортируются по полю id в порядке убывания.
Вы можете изменить сортировку с помощью свойств $sortColumn и $sortDirection.
protected string $sortColumn = 'created_at';
protected string $sortDirection = 'DESC';
protected string $sortColumn = 'created_at';
protected string $sortDirection = 'DESC';
protected string $sortColumn = 'created_at';
protected string $sortDirection = 'DESC';
protected string $sortColumn = 'created_at';
protected string $sortDirection = 'DESC';
protected string $sortColumn = 'created_at';
protected string $sortDirection = 'DESC';
По умолчанию MoonShine использует стандартную пагинацию Laravel.
Вы можете переключиться на cursor pagination или simple pagination с помощью свойств $cursorPaginate и $simplePaginate.
protected bool $cursorPaginate = true;
protected bool $cursorPaginate = true;
protected bool $cursorPaginate = true;
protected bool $cursorPaginate = true;
protected bool $cursorPaginate = true;
protected bool $simplePaginate = true;
protected bool $simplePaginate = true;
protected bool $simplePaginate = true;
protected bool $simplePaginate = true;
protected bool $simplePaginate = true;
По умолчанию в ресурсе включен "Асинхронный режим".
Чтобы его выключить, переопределите свойство $isAsync в ресурсе или на отдельных CRUD страницах.
protected bool $isAsync = false;
protected bool $isAsync = false;
protected bool $isAsync = false;
protected bool $isAsync = false;
protected bool $isAsync = false;
Подробнее об асинхронной загрузке таблицы можно узнать в разделе TableBuilder.
Подробнее об асинхронной отправке форм можно узнать в разделе FormBuilder.
Lazy-режим откладывает загрузку индексной таблицы до момента, когда она станет видимой на странице.
protected bool $isLazy = true;
protected bool $isLazy = true;
protected bool $isLazy = true;
protected bool $isLazy = true;
protected bool $isLazy = true;
Вы можете добавить валидацию для полей формы ресурса, используя стандартные правила валидации Laravel.
Правила валидации
Метод rules() позволяет определить правила валидации для полей.
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
'content' => ['required', 'string'],
'email' => ['sometimes', 'email'],
];
}
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
'content' => ['required', 'string'],
'email' => ['sometimes', 'email'],
];
}
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
'content' => ['required', 'string'],
'email' => ['sometimes', 'email'],
];
}
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
'content' => ['required', 'string'],
'email' => ['sometimes', 'email'],
];
}
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
'content' => ['required', 'string'],
'email' => ['sometimes', 'email'],
];
}
Сообщения валидации
Метод validationMessages() позволяет переопределить сообщения об ошибках валидации.
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
];
}
public function validationMessages(): array
{
return [
'title.required' => 'Заголовок обязателен для заполнения',
'title.min' => 'Заголовок должен содержать минимум :min символов',
];
}
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
];
}
public function validationMessages(): array
{
return [
'title.required' => 'Заголовок обязателен для заполнения',
'title.min' => 'Заголовок должен содержать минимум :min символов',
];
}
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
];
}
public function validationMessages(): array
{
return [
'title.required' => 'Заголовок обязателен для заполнения',
'title.min' => 'Заголовок должен содержать минимум :min символов',
];
}
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
];
}
public function validationMessages(): array
{
return [
'title.required' => 'Заголовок обязателен для заполнения',
'title.min' => 'Заголовок должен содержать минимум :min символов',
];
}
protected function rules(DataWrapperContract $item): array
{
return [
'title' => ['required', 'string', 'min:5'],
];
}
public function validationMessages(): array
{
return [
'title.required' => 'Заголовок обязателен для заполнения',
'title.min' => 'Заголовок должен содержать минимум :min символов',
];
}
Подготовка данных для валидации
Метод prepareForValidation() позволяет изменить данные перед валидацией.
public function prepareForValidation(): void
{
request()->merge([
'slug' => request()
->string('slug')
->lower()
->value(),
]);
}
public function prepareForValidation(): void
{
request()->merge([
'slug' => request()
->string('slug')
->lower()
->value(),
]);
}
public function prepareForValidation(): void
{
request()->merge([
'slug' => request()
->string('slug')
->lower()
->value(),
]);
}
public function prepareForValidation(): void
{
request()->merge([
'slug' => request()
->string('slug')
->lower()
->value(),
]);
}
public function prepareForValidation(): void
{
request()->merge([
'slug' => request()
->string('slug')
->lower()
->value(),
]);
}
Precognitive валидация
Свойство $isPrecognitive позволяет включить precognitive валидацию для формы.
protected bool $isPrecognitive = true;
protected bool $isPrecognitive = true;
protected bool $isPrecognitive = true;
protected bool $isPrecognitive = true;
protected bool $isPrecognitive = true;
Precognitive валидация позволяет валидировать поля формы в реальном времени при вводе данных.
Все страницы в MoonShine имеют Layout и у каждой страницы он может быть свой.
По умолчанию при установке MoonShine добавляет базовый MoonShineLayout в директорию app/MoonShine/Layouts.
В Layout кастомизируется всё, что отвечает за внешний вид ваших страниц и это касается также и навигации.
Чтобы добавить раздел в меню, необходимо объявить его через метод menu() в Layout.
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\AppLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends AppLayout
{
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(MoonShineUserResource::class),
MenuItem::make(MoonShineUserRoleResource::class),
]),
MenuItem::make(PostResource::class),
];
}
}
namespaces
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\AppLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends AppLayout
{
// ...
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(MoonShineUserResource::class),
MenuItem::make(MoonShineUserRoleResource::class),
]),
MenuItem::make(PostResource::class),
// ...
];
}
}
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\AppLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends AppLayout
{
// ...
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(MoonShineUserResource::class),
MenuItem::make(MoonShineUserRoleResource::class),
]),
MenuItem::make(PostResource::class),
// ...
];
}
}
namespaces
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\AppLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends AppLayout
{
// ...
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(MoonShineUserResource::class),
MenuItem::make(MoonShineUserRoleResource::class),
]),
MenuItem::make(PostResource::class),
// ...
];
}
}
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\AppLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends AppLayout
{
// ...
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(MoonShineUserResource::class),
MenuItem::make(MoonShineUserRoleResource::class),
]),
MenuItem::make(PostResource::class),
// ...
];
}
}
О расширенных настройках Layout можно узнать в разделе Layout.
О расширенных настройках MenuManager можно узнать в разделе Menu.
По умолчанию alias ресурса, который используется в url, генерируется на основе наименования класс в kebab-case, например:
MoonShineUserResource -> moon-shine-user-resource.
Для того чтобы изменить alias, можно воспользоваться свойством ресурса $alias или методом getAlias().
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
// ...
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
Если в url детальной страницы или страницы редактирования присутствует параметр resourceItem, то в ресурсе вы можете получить доступ к текущему элементу через метод getItem().
$this->getItem();
$this->getItem();
$this->getItem();
$this->getItem();
$this->getItem();
Через метод getModel() можно получить доступ к модели.
$this->getModel();
$this->getModel();
$this->getModel();
$this->getModel();
$this->getModel();
Вы можете добавлять, редактировать и просматривать записи прямо на странице со списком в модальном окне.
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
// ...
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
// ...
}
По умолчанию при создании и редактировании записи осуществляется редирект на страницу с формой, но это поведение можно контролировать.
Через свойство в ресурсе:
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
namespaces
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
namespaces
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
Через метод:
public function getRedirectAfterSave(): string
{
return '/';
}
public function getRedirectAfterSave(): string
{
return '/';
}
public function getRedirectAfterSave(): string
{
return '/';
}
public function getRedirectAfterSave(): string
{
return '/';
}
public function getRedirectAfterSave(): string
{
return '/';
}
Также доступен редирект после удаления:
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
Часто бывает, что необходимо создать ресурс, в котором будет исключена возможность удалять, или добавлять, или редактировать.
И здесь речь не об авторизации, а о глобальном исключении этих разделов.
Делается это крайне просто за счет метода activeActions() в ресурсе.
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Support\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
;
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Support\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
// ->only(Action::VIEW)
;
}
}
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Support\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
// ->only(Action::VIEW)
;
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Support\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
// ->only(Action::VIEW)
;
}
}
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Support\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
// ->only(Action::VIEW)
;
}
}
Также можно просто создать новый список, например:
use MoonShine\Support\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
namespaces
use MoonShine\Support\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
use MoonShine\Support\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
namespaces
use MoonShine\Support\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
use MoonShine\Support\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
Для модификации основного компонента IndexPage, FormPage или DetailPage страницы из ресурса можно переопределить соответствующие методы modifyListComponent(), modifyFormComponent() и modifyDetailComponent().
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
Лучший способ изменить компоненты страниц - это опубликовать страницы и взаимодействовать через них.
Но, если вы хотите быстро добавить компоненты на страницы, то можете воспользоваться методами ресурса pageComponents(), indexPageComponents(), formPageComponents() и detailPageComponents().
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
namespaces
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
// or indexPageComponents/formPageComponents/detailPageComponents
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
// or indexPageComponents/formPageComponents/detailPageComponents
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
namespaces
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
// or indexPageComponents/formPageComponents/detailPageComponents
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
// or indexPageComponents/formPageComponents/detailPageComponents
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
Компоненты будут добавлены в bottomLayer.
Resource имеет несколько различных методов подключения к различным частям своего жизненного цикла. Давайте пройдемся по ним:
Метод onLoad() дает возможность интегрироваться в момент когда ресурс загружен и в данный момент является активным.
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected function onLoad(): void
{
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onLoad(): void
{
// ...
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onLoad(): void
{
// ...
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onLoad(): void
{
// ...
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onLoad(): void
{
// ...
}
}
Вы также можете подключить trait к ресурсу и внутри trait добавить метод согласно конвенции наименований - load{TraitName} и через трейт обратиться к onLoad ресурса.
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
}
namespaces
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
// ...
}
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
// ...
}
namespaces
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
// ...
}
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
// ...
}
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
namespaces
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
namespaces
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
Метод onBoot() дает возможность интегрироваться в момент когда MoonShine создает экземпляр ресурса в системе.
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected function onBoot(): void
{
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onBoot(): void
{
// ...
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onBoot(): void
{
// ...
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onBoot(): void
{
// ...
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onBoot(): void
{
// ...
}
}
Вы также можете подключить trait к ресурсу и внутри trait добавить метод согласно конвенции наименований - boot{TraitName} и через трейт обратиться к onBoot() ресурса.
use MoonShine\AssetManager\Css;
use MoonShine\AssetManager\Js;
protected function onLoad(): void
{
$this->getAssetManager()
->add(Css::make('/css/app.css'))
->append(Js::make('/js/app.js'));
}
namespaces
use MoonShine\AssetManager\Css;
use MoonShine\AssetManager\Js;
protected function onLoad(): void
{
$this->getAssetManager()
->add(Css::make('/css/app.css'))
->append(Js::make('/js/app.js'));
}
use MoonShine\AssetManager\Css;
use MoonShine\AssetManager\Js;
protected function onLoad(): void
{
$this->getAssetManager()
->add(Css::make('/css/app.css'))
->append(Js::make('/js/app.js'));
}
namespaces
use MoonShine\AssetManager\Css;
use MoonShine\AssetManager\Js;
protected function onLoad(): void
{
$this->getAssetManager()
->add(Css::make('/css/app.css'))
->append(Js::make('/js/app.js'));
}
use MoonShine\AssetManager\Css;
use MoonShine\AssetManager\Js;
protected function onLoad(): void
{
$this->getAssetManager()
->add(Css::make('/css/app.css'))
->append(Js::make('/js/app.js'));
}
Если ресурс в режиме "async", то вы можете модифицировать ответ:
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Crud\JsonResponse;
public function modifyDestroyResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifySaveResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Crud\JsonResponse;
public function modifyDestroyResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifySaveResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Crud\JsonResponse;
public function modifyDestroyResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifySaveResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Crud\JsonResponse;
public function modifyDestroyResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifySaveResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Crud\JsonResponse;
public function modifyDestroyResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifySaveResponse(JsonResponse $response): JsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}
Вы можете изменить логику операций сохранения, удаления и массового удаления записей в ModelResource с помощью своих обработчиков и атрибутов SaveHandler, DestroyHandler и MassDestroyHandler.
В обработчик операции сохранения прокидывается массив $data, который уже прошёл через метод apply() у полей формы.
Пример использования:
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[DestroyHandler(MoonShineUserRoleHandlers::class, 'destroy')]
#[MassDestroyHandler(MoonShineUserRoleHandlers::class, 'massDestroy')]
#[SaveHandler(MoonShineUserRoleHandlers::class, 'save')]
class MoonShineUserRoleResource extends ModelResource
{
}
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[DestroyHandler(MoonShineUserRoleHandlers::class, 'destroy')]
#[MassDestroyHandler(MoonShineUserRoleHandlers::class, 'massDestroy')]
#[SaveHandler(MoonShineUserRoleHandlers::class, 'save')]
class MoonShineUserRoleResource extends ModelResource
{
//...
}
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[DestroyHandler(MoonShineUserRoleHandlers::class, 'destroy')]
#[MassDestroyHandler(MoonShineUserRoleHandlers::class, 'massDestroy')]
#[SaveHandler(MoonShineUserRoleHandlers::class, 'save')]
class MoonShineUserRoleResource extends ModelResource
{
//...
}
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[DestroyHandler(MoonShineUserRoleHandlers::class, 'destroy')]
#[MassDestroyHandler(MoonShineUserRoleHandlers::class, 'massDestroy')]
#[SaveHandler(MoonShineUserRoleHandlers::class, 'save')]
class MoonShineUserRoleResource extends ModelResource
{
//...
}
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[DestroyHandler(MoonShineUserRoleHandlers::class, 'destroy')]
#[MassDestroyHandler(MoonShineUserRoleHandlers::class, 'massDestroy')]
#[SaveHandler(MoonShineUserRoleHandlers::class, 'save')]
class MoonShineUserRoleResource extends ModelResource
{
//...
}
Класс с методами для обработки операций может выглядеть так:
final readonly class MoonShineUserRoleHandlers
{
public function save(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
public function destroy(MoonshineUserRole $model): bool
{
return $model->delete();
}
public function massDestroy(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}
final readonly class MoonShineUserRoleHandlers
{
public function save(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
public function destroy(MoonshineUserRole $model): bool
{
return $model->delete();
}
public function massDestroy(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}
final readonly class MoonShineUserRoleHandlers
{
public function save(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
public function destroy(MoonshineUserRole $model): bool
{
return $model->delete();
}
public function massDestroy(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}
final readonly class MoonShineUserRoleHandlers
{
public function save(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
public function destroy(MoonshineUserRole $model): bool
{
return $model->delete();
}
public function massDestroy(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}
final readonly class MoonShineUserRoleHandlers
{
public function save(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
public function destroy(MoonshineUserRole $model): bool
{
return $model->delete();
}
public function massDestroy(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}
Вы также можете использовать классы-обработчики вместо методов — в этом случае они должны реализовывать метод __invoke():
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[SaveHandler(MoonShineUserRoleSaveHandler::class)]
#[DestroyHandler(MoonShineUserRoleDestroyHandler::class)]
#[MassDestroyHandler(MoonShineUserRoleMassDestroyHandler::class)]
class MoonShineUserRoleResource extends ModelResource
{
}
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[SaveHandler(MoonShineUserRoleSaveHandler::class)]
#[DestroyHandler(MoonShineUserRoleDestroyHandler::class)]
#[MassDestroyHandler(MoonShineUserRoleMassDestroyHandler::class)]
class MoonShineUserRoleResource extends ModelResource
{
//..
}
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[SaveHandler(MoonShineUserRoleSaveHandler::class)]
#[DestroyHandler(MoonShineUserRoleDestroyHandler::class)]
#[MassDestroyHandler(MoonShineUserRoleMassDestroyHandler::class)]
class MoonShineUserRoleResource extends ModelResource
{
//..
}
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[SaveHandler(MoonShineUserRoleSaveHandler::class)]
#[DestroyHandler(MoonShineUserRoleDestroyHandler::class)]
#[MassDestroyHandler(MoonShineUserRoleMassDestroyHandler::class)]
class MoonShineUserRoleResource extends ModelResource
{
//..
}
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Crud\Attributes\DestroyHandler;
use MoonShine\Crud\Attributes\MassDestroyHandler;
use MoonShine\Crud\Attributes\SaveHandler;
#[SaveHandler(MoonShineUserRoleSaveHandler::class)]
#[DestroyHandler(MoonShineUserRoleDestroyHandler::class)]
#[MassDestroyHandler(MoonShineUserRoleMassDestroyHandler::class)]
class MoonShineUserRoleResource extends ModelResource
{
//..
}
final readonly class MoonShineUserRoleSaveHandler
{
public function __invoke(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
}
final readonly class MoonShineUserRoleDestroyHandler
{
public function __invoke(MoonshineUserRole $model): bool
{
return $model->delete();
}
}
final readonly class MoonShineUserRoleMassDestroyHandler
{
public function __invoke(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}
final readonly class MoonShineUserRoleSaveHandler
{
public function __invoke(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
}
final readonly class MoonShineUserRoleDestroyHandler
{
public function __invoke(MoonshineUserRole $model): bool
{
return $model->delete();
}
}
final readonly class MoonShineUserRoleMassDestroyHandler
{
public function __invoke(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}
final readonly class MoonShineUserRoleSaveHandler
{
public function __invoke(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
}
final readonly class MoonShineUserRoleDestroyHandler
{
public function __invoke(MoonshineUserRole $model): bool
{
return $model->delete();
}
}
final readonly class MoonShineUserRoleMassDestroyHandler
{
public function __invoke(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}
final readonly class MoonShineUserRoleSaveHandler
{
public function __invoke(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
}
final readonly class MoonShineUserRoleDestroyHandler
{
public function __invoke(MoonshineUserRole $model): bool
{
return $model->delete();
}
}
final readonly class MoonShineUserRoleMassDestroyHandler
{
public function __invoke(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}
final readonly class MoonShineUserRoleSaveHandler
{
public function __invoke(MoonshineUserRole $model, array $data): MoonshineUserRole
{
$model->fill($data);
$model->save();
return $model;
}
}
final readonly class MoonShineUserRoleDestroyHandler
{
public function __invoke(MoonshineUserRole $model): bool
{
return $model->delete();
}
}
final readonly class MoonShineUserRoleMassDestroyHandler
{
public function __invoke(array $ids): void
{
foreach ($ids as $id) {
MoonshineUserRole::query()->whereKey($id)->delete();
}
}
}