# Models

Describe SurrealDB tables as PHP classes in Surqlize, using attributes for the table name, record id, casts, schema, and specialised fields.

A Surqlize model is a PHP class that maps to a SurrealDB table. It extends `Surqlize\Model\Model`, declares its table with the `#[Table]` attribute, and exposes the record's fields as typed properties.

```php
use Surqlize\Attributes\Id;
use Surqlize\Attributes\Table;
use Surqlize\Model\Model;
use SurrealDB\SDK\Types\RecordId;

#[Table('user')]
final class User extends Model
{
    #[Id]
    public RecordId $id;

    public string $name;
    public int $age;
}
```

The property marked `#[Id]` holds the record's [`RecordId`](/docs/reference/php/v2/api/data-types.md#recordid) from the SDK. Property names map to SurrealDB field names directly, so a `name` property reads and writes the `name` field.

## Attributes

Surqlize describes a model through attributes in the `Surqlize\Attributes` namespace.

| Attribute | Target | Purpose |
|-----------|--------|---------|
| `#[Table('user')]` | class | Maps the model to a table |
| `#[Id]` | property | Marks the record id property (a `RecordId`) |
| `#[Cast(Address::class)]` | property | Hydrates a nested value as another model |
| `#[Schema(UserSchema::class)]` | class | Links the model to a [schema](/docs/reference/php/libraries/surqlize/schema.md) definition |
| `#[Search(analyzer: 'english')]` | property | Marks a [full-text search](/docs/reference/php/libraries/surqlize/search-vector-geometry.md) field |
| `#[Vector(dimension: 3)]` | property | Marks a [vector](/docs/reference/php/libraries/surqlize/search-vector-geometry.md) field and its dimension |
| `#[Geometry]` | property | Marks a [geometry](/docs/reference/php/libraries/surqlize/search-vector-geometry.md) field |
| `#[Edge('has_address', in: User::class, out: Address::class)]` | class | Defines a graph [edge](/docs/reference/php/libraries/surqlize/edges-and-graph.md) model |

The `#[Vector]` attribute also accepts a `distance` (default `cosine`), `#[Geometry]` accepts a `type` (default `geometry`), and `#[Search]` accepts an optional `analyzer`.

## Nested models

Use `#[Cast]` to hydrate an embedded object or a record link as another model. The nested class is itself a model.

```php
use Surqlize\Attributes\Cast;
use Surqlize\Attributes\Table;
use Surqlize\Model\Model;

#[Table('address')]
final class Address extends Model
{
    public string $street;
    public int $number;
    public string $postcode;
}

#[Table('user')]
final class User extends Model
{
    #[Id]
    public RecordId $id;

    public string $name;

    #[Cast(Address::class)]
    public ?Address $address = null;
}
```

## What a model gives you

Extending `Model` provides static query entry points and instance data operations.

| Method | Purpose |
|--------|---------|
| `select()` | Start a `SELECT` with fields or a typed callback |
| `query()` | Start `SELECT *` for the table |
| `selectValue()` | Start a `SELECT VALUE` query |
| `fields()` | Resolve the model's typed field set |
| `relate()` | Start a model-first [relation](/docs/reference/php/libraries/surqlize/edges-and-graph.md) builder |
| `create()`, `createQuery()`, `upsert()`, `save()`, `delete()` | [Persist](/docs/reference/php/libraries/surqlize/mutations.md) a record |
| `all()`, `find()`, `findOrFail()`, `count()`, `exists()`, `refresh()` | Read or reload records |
| `toArray()` | Serialise the initialised properties to an array |

These are covered in [Querying](/docs/reference/php/libraries/surqlize/querying.md) and [Mutations](/docs/reference/php/libraries/surqlize/mutations.md).

## Learn more

- [Connections](/docs/reference/php/libraries/surqlize/connections.md) to register the executor models run through
- [Querying](/docs/reference/php/libraries/surqlize/querying.md) for the typed query builder
- [Schema](/docs/reference/php/libraries/surqlize/schema.md) to define tables and fields in the database
