---
title: "Form structure — Forms for Laravel | Roundly"
description: "Forms hold ordered groups (steps), groups hold fields. Create them as plain Eloquent models and read the dotted field path."
url: https://roundly-consulting.com/open-source/docs/forms-for-laravel/form-structure
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Forms for Laravel](https://roundly-consulting.com/open-source/docs/forms-for-laravel.md)

# Form structure

A form has groups — think steps or sections — and each group has fields. Every record carries a key that is unique within its parent among live records (form keys are globally unique; a soft-deleted record frees its key). You can create the structure with the models directly:

```php
use RoundlyConsulting\Forms\Models\Form;
use RoundlyConsulting\Forms\Models\Group;
use RoundlyConsulting\Forms\Models\Field;

$form = Form::create([
    'name' => 'My Form',
    'key' => 'my-form',
    'is_public' => true,        // optional, defaults to false
    'expires_at' => null,       // optional nullable datetime
]);

$group = Group::create([
    'form_id' => $form->getKey(),
    'name' => 'First Step',
    'key' => 'first-step',
    'order' => 0,
]);

$field = Field::create([
    'form_id' => $form->getKey(),
    'group_id' => $group->getKey(),
    'name' => 'Name',
    'key' => 'name',
    'help' => 'Enter your name',
    'type' => 'text',
    'validations' => ['required', 'string'],
    'options' => null,          // e.g. ['CZ' => 'Czechia', 'SK' => 'Slovakia']
    'autofill' => null,
    'order' => 0,
]);
```

## Field paths and request shape

Each field exposes a dotted path() built from form.key, group.key and field.key (e.g. my-form.first-step.name). That path is the request key the resolver reads, so your HTML inputs are nested per form and group:

```html
<form method="POST" action="{{ route('contact.store') }}">
    @csrf
    <input name="contact[details][name]">
    <input name="contact[details][email]" type="email">
    <textarea name="contact[message][body]"></textarea>
    <button type="submit">Send</button>
</form>
```

## Relations and helpers

```php
$field->path();             // 'my-form.first-step.name' — the request key

$form->groups;               // HasMany<Group>
$form->fields;               // HasManyThrough<Field> (through groups)
$form->submissions;          // HasMany<Submission> — one row per field per submission
$group->fields;              // HasMany<Field>
$field->form;                // BelongsTo<Form>
$field->group;               // BelongsTo<Group>

$form->isExpired();              // expires_at has passed
$form->isAcceptingSubmissions(); // is_public and not expired
$field->isRequired();            // has a plain 'required' rule (required_if & co. don't count)
$field->hasOptions();            // options set and non-empty
$field->hasValidations();        // validations set and non-empty
$field->resolver();              // the Resolver mapped to the field's type
```

Field columns options, validations, conditions and messages are cast to arrays. For anything beyond a one-off, prefer the fluent builder in the next section — it creates the whole structure in one transaction and assigns every order for you.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/forms-for-laravel.md)
