Resources
A resource is the Qore definition for one Eloquent model.
Resources extend QoreResource<TModel> and describe how that model appears in Qore: CRUD pages, fields, permissions, actions, relation tables, global search, logbook entries and URLs.
Use a resource when a model needs the standard application surface. A working resource normally has five app pieces:
- the resource class;
- registration in
AppServiceProvider; - seeded permissions;
- a model policy;
- a menu item.
Create A Resource Class
Create the resource in app/Resources. This example assumes an App\Models\Product model with name and price columns.
<?php
namespace App\Resources;
use App\Models\Product;
use Illuminate\Database\Eloquent\Model;
use Qore\Next\System\Field\Field;
use Qore\Next\System\Fields\CreatedAtField;
use Qore\Next\System\Fields\NumberField;
use Qore\Next\System\Fields\TextField;
use Qore\Next\System\Fields\UpdatedAtField;
use Qore\Next\System\Resource\QoreResource;
/**
* @extends QoreResource<Product>
*/
class ProductResource extends QoreResource
{
/**
* @return class-string<Product>
*/
public function modelClass(): string
{
return Product::class;
}
public function labelSingular(): string
{
return __('common.products.singular');
}
public function labelPlural(): string
{
return __('common.products.plural');
}
/**
* @param Product $model
*/
public function modelTitle(Model $model): string
{
return $model->name;
}
public function icon(): string
{
return 'package';
}
/**
* @return Field[]
*/
public function fields(): array
{
return [
TextField::make('name', __('common.name'))
->setRules(fn () => ['required', 'string', 'max:255']),
NumberField::make('price', __('common.price'))
->setRules(fn () => ['required', 'numeric', 'min:0'])
->setPrecision(2),
CreatedAtField::make(),
UpdatedAtField::make(),
];
}
}
ProductResource becomes the resource name products. Qore uses that name for default URLs and permission names, such as view any products.
At minimum a resource defines:
modelClass()labelSingular()labelPlural()icon()fields()
Register The Resource
Register resources in AppServiceProvider::register() so Qore can expose their routes, globals, relation options and menu metadata.
use App\Resources\ProductResource;
use function Qore\Next\System\Helpers\qore;
public function register(): void
{
qore()
->registerResource(new UserResource)
->registerResource(new ProductResource);
}
Registering the resource does not grant access by itself. Permissions and policies still decide what the user may do.
Seed Permissions
Add CRUDA permissions for the resource in database/seeders/PermissionSeeder.php.
use Illuminate\Database\Seeder;
use Qore\Next\System\Models\Permission;
use function Qore\Next\System\Helpers\admin_role;
use function Qore\Next\System\Helpers\qore;
class PermissionSeeder extends Seeder
{
public function run(): void
{
qore()->permissions()->cruda('products');
admin_role()->givePermissions(Permission::query()->select('id')->get());
}
}
cruda('products') creates the default resource permissions:
view any productsview productscreate productsupdate productsdelete products
Use the same resource name everywhere unless the resource overrides its permission methods. See Permissions for custom permission names.
Create The Policy
Create a policy for the model in app/Policies/ProductPolicy.php.
namespace App\Policies;
use App\Models\Product;
use App\Models\User;
class ProductPolicy
{
public function viewAny(User $user): bool
{
return $user->hasPermissionToViewAny('products');
}
public function view(User $user, Product $model): bool
{
return $user->hasPermissionToView('products', $model);
}
public function create(User $user): bool
{
return $user->hasPermissionToCreate('products');
}
public function update(User $user, Product $model): bool
{
return $user->hasPermissionToUpdate('products', $model);
}
public function delete(User $user, Product $model): bool
{
return $user->hasPermissionToDelete('products', $model);
}
}
Laravel auto-discovers policies that follow the normal App\Models\Product and App\Policies\ProductPolicy naming convention. Register the policy manually only when the class lives outside that convention:
Gate::policy(Product::class, ProductPolicy::class);
Add It To The Menu
Add the resource to the application menu, usually in app/Menu/AppMenu.php.
use function Qore\Next\System\Helpers\qore;
$this->addResourceMenuItem(resource: qore()->getResourceOrFail('products'));
addResourceMenuItem() uses the resource label, icon, index URL and getViewAnyPermissions() automatically. If the user cannot viewAny, the frontend hides the menu item from the globals payload.
Resource Checklist
When a resource does not show up, check these in order:
- The resource is registered in
AppServiceProvider::register(). - The resource name used in permissions matches
ProductResource -> products. - The permission seeder has run and the current role has the permissions.
- The policy returns
truefor the action you are testing. - The menu includes the resource or a custom menu item that points to it.
Common Overrides
Most resources start with the required methods and override only what changes the user experience:
modelTitle(Model $model): stringfor readable titles.indexQuery(): Builderfor default scoping and eager loading.indexTabs(): TableTab[]for index table tabs.indexLayout(): Node,createLayout(): Node,detailLayout(Model $model): NodeandeditLayout(Model $model): Nodefor custom page layouts.actions(): ResourceAction[]for bulk and detail actions.alerts(): ResourceAlert[]for detail-page warnings or notices.getGlobalSearchFields(): Field[]andglobalSearchNode(Model $model): Nodefor search behaviour.
See the focused pages for the details: