Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
Model Patterns
rhino-project/rhino-laravel
cursor
eloquent
models
validation
multi-tenancy
mass-assignment
query-filters
middleware

Model structure conventions for the laravel-global-controller package

Install
php artisan boost:add-skill rhino-project/rhino-laravel

Save this content to: .cursor/rules/model-patterns.mdc

# Model Patterns

## Required Traits

Every model MUST use these traits:

```php
use HasFactory, SoftDeletes, HasValidation, HidableColumns;
```

For models with a direct `organization_id` column, also add `BelongsToOrganization`.

## Required Properties

```php
// Mass assignment
protected $fillable = ['field1', 'field2'];

// Validation rules (full definitions)
protected $validationRules = [
    'field1' => 'required|string|max:255',
    'field2' => 'nullable|string',
];

// Fields validated on store
protected $validationRulesStore = ['field1', 'field2'];

// Fields validated on update
protected $validationRulesUpdate = ['field1', 'field2'];

// Query Builder configuration
public static $allowedFilters = ['field1'];
public static $allowedSorts = ['field1', 'created_at'];
public static $defaultSort = 'created_at';
public static $allowedFields = ['id', 'field1', 'field2', 'created_at'];
public static $allowedIncludes = ['relationship'];
```

## Multi-Tenant Ownership

Rhino auto-detects the ownership path to Organization by introspecting BelongsTo relationships.

```php
// Direct: model has organization_id
use BelongsToOrganization; // trait handles it

// Indirect: auto-detected from BelongsTo relationships.
// Post -> Blog -> Organization is resolved automatically.
```

## Optional Route Properties

```php
// Middleware applied to all CRUD actions
public static array $middleware = [\App\Http\Middleware\LogAccess::class];

// Middleware applied to specific actions
public static array $middlewareActions = [
    'store' => [\App\Http\Middleware\ValidatePayload::class],
];

// Disable specific CRUD actions
public static array $exceptActions = ['destroy'];
```

## DON'Ts

- Don't put authorization logic in the model
- Don't define inline query scopes for authorization — create separate Scope classes in `app/Models/Scopes/`
- Don't add `organization_id` to `$fillable` without using the `BelongsToOrganization` trait
- Don't skip validation rules — every fillable field should have a rule

Model Patterns

Required Traits

Every model MUST use these traits:

use HasFactory, SoftDeletes, HasValidation, HidableColumns;

For models with a direct organization_id column, also add BelongsToOrganization.

Required Properties

// Mass assignment
protected $fillable = ['field1', 'field2'];

// Validation rules (full definitions)
protected $validationRules = [
    'field1' => 'required|string|max:255',
    'field2' => 'nullable|string',
];

// Fields validated on store
protected $validationRulesStore = ['field1', 'field2'];

// Fields validated on update
protected $validationRulesUpdate = ['field1', 'field2'];

// Query Builder configuration
public static $allowedFilters = ['field1'];
public static $allowedSorts = ['field1', 'created_at'];
public static $defaultSort = 'created_at';
public static $allowedFields = ['id', 'field1', 'field2', 'created_at'];
public static $allowedIncludes = ['relationship'];

Multi-Tenant Ownership

Rhino auto-detects the ownership path to Organization by introspecting BelongsTo relationships.

// Direct: model has organization_id
use BelongsToOrganization; // trait handles it

// Indirect: auto-detected from BelongsTo relationships.
// Post -> Blog -> Organization is resolved automatically.

Optional Route Properties

// Middleware applied to all CRUD actions
public static array $middleware = [\App\Http\Middleware\LogAccess::class];

// Middleware applied to specific actions
public static array $middlewareActions = [
    'store' => [\App\Http\Middleware\ValidatePayload::class],
];

// Disable specific CRUD actions
public static array $exceptActions = ['destroy'];

DON'Ts

  • Don't put authorization logic in the model
  • Don't define inline query scopes for authorization — create separate Scope classes in app/Models/Scopes/
  • Don't add organization_id to $fillable without using the BelongsToOrganization trait
  • Don't skip validation rules — every fillable field should have a rule
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource