Skip to main content

Overview

BaseModel extends Laravel’s Eloquent Model with advanced features including:
  • Validation: Built-in validation with scenario support (create/update)
  • Hierarchy: Self-referencing tree structures with ancestor/descendant traversal
  • Role-based field restrictions: Control field access per Spatie role
  • Parent model support: Single Table Inheritance (STI) pattern
  • MongoDB relations: Custom relation helpers for MongoDB connections
All models in your application should extend BaseModel to leverage these features.

Constants

MODEL

const MODEL = '';
The name of the model used for array parameter wrapping. Example:
class User extends BaseModel
{
    const MODEL = 'user';
}
// Expects input: ['user' => ['name' => 'John', 'email' => '[email protected]']]

columns

const columns = [];
Default columns for the model. Used for field selection in queries. Example:
const columns = ['id', 'name', 'email', 'created_at'];

RELATIONS

const RELATIONS = [];
Defines allowed relations that can be eager loaded via API requests. Example:
const RELATIONS = ['posts', 'comments', 'roles'];
Only relations listed here can be loaded via the relations query parameter. This is a security feature.

PARENT

const PARENT = [];
Defines parent class information for Single Table Inheritance hierarchy. Example:
class Admin extends User
{
    const PARENT = [
        'class' => User::class
    ];
}

HIERARCHY_FIELD_ID

const HIERARCHY_FIELD_ID = null;
Field name for self-referencing hierarchy (e.g., parent_id, manager_id). Example:
class Category extends BaseModel
{
    const HIERARCHY_FIELD_ID = 'parent_id';
}

Properties

fieldsByRole

protected array $fieldsByRole = [];
Role-to-field restriction map. Declares which fields require specific Spatie roles to write.
fieldsByRole
array<string, list<string>>
default:"[]"
Maps role names to arrays of privileged field names
Example:
protected array $fieldsByRole = [
    'superadmin' => ['is_superuser', 'permissions'],
    'admin'      => ['status', 'role_id', 'is_verified'],
];
Behavior:
  • Fields NOT listed are writable by any authenticated user
  • Superusers bypass all restrictions
  • Multiple roles grant union of field access

scenario

protected string $scenario = 'create';
Current operation scenario (create or update). Used for context-aware validation.

fieldKeyUpdate

protected string|int|null $fieldKeyUpdate = null;
Reference column for update operations. Falls back to primary key when null.

Key Methods

getDeniedFieldsForUser()

public function getDeniedFieldsForUser(mixed $user): array
Returns fields the given user is NOT allowed to write.
user
mixed
required
The authenticated user model (must have Spatie’s hasRole() method)
return
list<string>
Array of field names the user cannot write
Algorithm:
  1. If $fieldsByRole is empty → return [] (no restrictions)
  2. If user has is_superuser = true → return []
  3. Build universe of all privileged fields
  4. Build allowed set from user’s roles
  5. Return universe − allowed
Example:
$user = auth()->user();
$deniedFields = $model->getDeniedFieldsForUser($user);
// ['is_superuser', 'permissions'] if user lacks superadmin role

Accessor Methods

getPrimaryKey()

public function getPrimaryKey(): string
Returns the model’s primary key name.

getFieldKeyUpdate()

public function getFieldKeyUpdate(): string|int|null
Returns the field used for updates (defaults to primary key).

getScenario()

public function getScenario(): string
Returns current validation scenario (create or update).

setScenario()

public function setScenario(string $scenario): void
Sets the validation scenario.

Hierarchy Methods

hasHierarchy()

public function hasHierarchy(): bool
Checks if model uses Single Table Inheritance (has PARENT defined).

hasHierarchyField()

public function hasHierarchyField(): bool
Checks if model supports self-referencing hierarchy.

getHierarchyFieldId()

public function getHierarchyFieldId(): ?string
Returns the hierarchy field name (e.g., parent_id).

hierarchyParent()

public function hierarchyParent(): ?BelongsTo
Defines BelongsTo relation to parent in hierarchy. Example:
$category = Category::find(1);
$parent = $category->hierarchyParent; // Parent category

hierarchyChildren()

public function hierarchyChildren(): HasMany
Defines HasMany relation to children in hierarchy. Example:
$category = Category::find(1);
$children = $category->hierarchyChildren; // Child categories

isHierarchyRoot()

public function isHierarchyRoot(): bool
Checks if record is root node (has no parent).

getHierarchyAncestors()

public function getHierarchyAncestors(): \Illuminate\Support\Collection
Returns all ancestors from parent to root. Example:
$category = Category::find(5);
$ancestors = $category->getHierarchyAncestors();
// Collection of parent, grandparent, great-grandparent, etc.

getHierarchyDescendants()

public function getHierarchyDescendants(?int $maxDepth = null, int $currentDepth = 0): \Illuminate\Support\Collection
Returns all descendants recursively.
maxDepth
int|null
default:"null"
Maximum depth to traverse (null = unlimited)
currentDepth
int
default:"0"
Current depth in recursion (internal use)
Example:
$category = Category::find(1);
$descendants = $category->getHierarchyDescendants(2); // 2 levels deep

Validation Methods

rules()

protected function rules(string $scenario): array
Define validation rules per scenario. Override in your model. Example:
protected function rules(string $scenario): array
{
    if ($scenario === 'create') {
        return [
            'email' => 'required|email|unique:users',
            'name' => 'required|min:3',
        ];
    }
    return [
        'email' => 'email',
        'name' => 'min:3',
    ];
}

self_validate()

public function self_validate(string $scenario = 'create', bool $specific = false, bool $validate_pk = true): array
Validates current model attributes.
scenario
string
default:"create"
Validation scenario (create or update)
specific
bool
default:"false"
If true, only validate fields present in attributes
validate_pk
bool
default:"true"
Include primary key in validation
return
array
[
  'success' => bool,
  'errors' => array,
  'model' => string // Model class name
]

validate_all()

public function validate_all(array $attributes, string $scenario = 'create', bool $specific = false): array
Validates model and all parent models in hierarchy.
attributes
array
required
Data to validate
scenario
string
default:"create"
Validation scenario
return
array
['success' => true] // or ['success' => false, 'errors' => [...]]

save_model()

public function save_model(array $attributes = [], string $scenario = 'create'): array
Validates and saves the model (and parent hierarchy if applicable).
attributes
array
default:"[]"
Attributes to save (uses current attributes if empty)
scenario
string
default:"create"
Operation scenario
return
array
[
  'success' => true,
  'model' => array // Saved attributes
]
// or on error:
[
  'success' => false,
  'errors' => array
]

Static Methods

create_model()

static public function create_model(array $params): array
Creates one or more model instances. Example:
// Single record
$result = User::create_model(['name' => 'John', 'email' => '[email protected]']);

// Multiple records
$result = User::create_model(['user' => [
    ['name' => 'John', 'email' => '[email protected]'],
    ['name' => 'Jane', 'email' => '[email protected]']
]]);

update_multiple()

static public function update_multiple(array $params): array
Updates multiple records at once. Example:
$result = User::update_multiple([
    ['id' => 1, 'status' => 'active'],
    ['id' => 2, 'status' => 'inactive']
]);

destroy_model()

static public function destroy_model(mixed $id): array
Deletes a model by ID.
return
array
['success' => true, 'model' => Model]

MongoDB Relation Methods

These methods enable relationships between SQL and MongoDB databases.

belongsToMongo()

public function belongsToMongo(
    string $related,
    ?string $foreignKey = null,
    ?string $ownerKey = null,
    ?string $relation = null
): MongoBelongTo
Defines a BelongsTo relationship with a MongoDB model. Example:
public function author()
{
    return $this->belongsToMongo(MongoUser::class, 'author_id');
}

hasManyMongo()

public function hasManyMongo(
    string $related,
    ?string $foreignKey = null,
    ?string $localKey = null
): MongoHasMany|HasMany
Defines a HasMany relationship with a MongoDB model. Example:
public function logs()
{
    return $this->hasManyMongo(MongoLog::class, 'user_id');
}

hasOneMongo()

public function hasOneMongo(
    string $related,
    ?string $foreignKey = null,
    ?string $localKey = null
): HasOneOrMany
Defines a HasOne relationship with a MongoDB model.

Usage Example

use Ronu\RestGenericClass\Core\Models\BaseModel;

class Category extends BaseModel
{
    const MODEL = 'category';
    const RELATIONS = ['parent', 'children', 'products'];
    const HIERARCHY_FIELD_ID = 'parent_id';
    
    protected $fillable = ['name', 'slug', 'parent_id', 'is_active'];
    
    protected array $fieldsByRole = [
        'admin' => ['is_active', 'featured']
    ];
    
    protected function rules(string $scenario): array
    {
        if ($scenario === 'create') {
            return [
                'name' => 'required|min:3|unique:categories',
                'slug' => 'required|unique:categories',
            ];
        }
        return [
            'name' => 'min:3',
        ];
    }
    
    public function products()
    {
        return $this->hasMany(Product::class);
    }
}

// Usage
$category = Category::find(1);
$children = $category->hierarchyChildren;
$ancestors = $category->getHierarchyAncestors();
$descendants = $category->getHierarchyDescendants(2);

// Validation
$result = $category->validate_all([
    'name' => 'Electronics',
    'slug' => 'electronics'
], 'create');

if ($result['success']) {
    // Save the category
}

BaseService

Service layer with query building and CRUD operations

RestController

Controller exposing RESTful API endpoints

Build docs developers (and LLMs) love