Eloquent Integration
Using FormAccessible Trait
Add the FormAccessible trait to your Eloquent models to enable form mutators. Form mutators allow you to transform model attributes specifically for display in forms, without affecting how they're stored or accessed elsewhere.
Form Mutator Pattern: form{AttributeName}Attribute($value)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use SpaanProductions\LaravelForm\Eloquent\FormAccessible;
class User extends Model
{
use FormAccessible;
protected $fillable = ['name', 'email', 'birth_date', 'salary'];
protected $casts = [
'birth_date' => 'datetime',
'salary' => 'decimal:2'
];
/**
* Form mutator for birth_date
* Formats the date specifically for form display
*/
public function formBirthDateAttribute($value)
{
return $value ? $value->format('Y-m-d') : null;
}
/**
* Form mutator for computed field
* Useful for read-only fields that combine multiple attributes
*/
public function formFullNameAttribute($value)
{
return $this->first_name . ' ' . $this->last_name;
}
/**
* Form mutator for salary
* Display without currency symbol in forms, but include it elsewhere
*/
public function formSalaryAttribute($value)
{
return number_format($value, 2, '.', '');
}
/**
* Regular accessor (for general display)
* Shows salary with currency symbol
*/
public function getSalaryAttribute($value)
{
return '$' . number_format($value, 2);
}
}
Key Benefits:
- Separation of Concerns: Different formatting for forms vs. display
- Date Handling: Automatically handles DateTime objects in form fields
- Computed Fields: Display derived values without storing them
- No Side Effects: Doesn't affect normal attribute access or database operations
Model Binding
// In your controller
public function edit(User $user)
{
return view('users.edit', compact('user'));
}
// In your Blade template
{{ Form::model($user, ['route' => ['users.update', $user->id], 'method' => 'PUT']) }}
{{ Form::text('name') }}
{{ Form::email('email') }}
{{ Form::date('birth_date') }}
{{ Form::text('full_name') }} {{-- Uses form mutator --}}
{{ Form::submit('Update User') }}
{{ Form::close() }}
Form Value Resolution
The Form Builder uses a specific priority order when determining what value to display in form fields. Understanding this order is crucial for debugging form behavior:
Priority Order (highest to lowest):
- Old Input - Values from the previous request (after validation failure)
- Request Data - Current request values (only when
considerRequest()is enabled) - Explicit Value - The value parameter you pass to the form method
- Model Attribute - Value from the bound model (with form mutators applied)
- Null - Default fallback
// Example demonstrating the priority order:
// 1. After validation failure, old input takes precedence
{{ Form::model($user, ['route' => 'users.store']) }}
{{-- If validation fails, this will show the previously submitted value --}}
{{ Form::text('name') }}
{{ Form::close() }}
// 2. With considerRequest(), current request data is used
{{ Form::open(['route' => 'search']) }}
{{ Form::considerRequest() }}
{{-- Will populate from current request query parameters --}}
{{ Form::text('query') }}
{{ Form::close() }}
// 3. Explicit values override model values
{{ Form::model($user, ['route' => 'users.update']) }}
{{-- Shows 'Default Name' instead of $user->name --}}
{{ Form::text('name', 'Default Name') }}
{{ Form::close() }}
// 4. Model values with form mutators
{{ Form::model($user, ['route' => 'users.update']) }}
{{-- If User has formBirthDateAttribute(), that mutator is applied --}}
{{ Form::date('birth_date') }}
{{ Form::close() }}
Accessing Nested Model Relationships:
The Form Builder supports dot notation for accessing nested relationships:
{{ Form::model($user, ['route' => 'profile.update']) }}
{{-- Access nested relationship attributes --}}
{{ Form::text('profile.bio') }}
{{ Form::text('address.city') }}
{{ Form::text('address.country.name') }}
{{-- Works with form mutators on nested models too --}}
{{ Form::date('profile.birth_date') }}
{{ Form::close() }}
Getting and Setting the Model:
// Set model after opening a form
$form = Form::open(['route' => 'users.store']);
Form::setModel($user);
// Get the current model
$currentModel = Form::getModel();
Een fout gevonden of een vraag? Maak een issue aan op GitHub.