Installation:
composer require laravelbook/ardent:3.*
Add the service provider to config/app.php:
'providers' => [
// ...
LaravelBook\Ardent\ArdentServiceProvider::class,
],
Extend a Model:
Use Ardent trait in your Eloquent model:
use LaravelBook\Ardent\Ardent;
class User extends Model
{
use Ardent;
}
First Use Case: Define validation rules directly in the model:
class User extends Model
{
use Ardent;
protected $rules = [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
];
}
Validate on save:
$user = new User(['name' => 'John', 'email' => 'invalid-email']);
if ($user->isValid()) {
$user->save(); // Automatically validates
}
$rules: Define validation rules per model.$fillable: Override default fillable attributes.isValid(): Check validation status.validate(): Manually trigger validation.Model-Level Validation:
// Define rules in model
class Post extends Model
{
use Ardent;
protected $rules = [
'title' => 'required|string|max:255',
'content' => 'required|string',
'published_at' => 'nullable|date',
];
}
// Validate on create/update
$post = new Post($request->all());
if ($post->isValid()) {
$post->save(); // Fails silently if invalid
}
Dynamic Rules: Use closures for dynamic validation:
protected $rules = [
'email' => function ($email) {
return $email ? 'required|email' : 'nullable';
},
];
Custom Validation Logic: Extend validation with custom methods:
use LaravelBook\Ardent\Validation\ValidatesWith;
class User extends Model
{
use Ardent, ValidatesWith;
protected $rules = [
'password' => 'required|min:8|confirmed',
];
public function validatePassword($attribute, $value, $parameters)
{
if (strtolower($value) === 'password') {
return 'Password cannot be "password"';
}
}
}
Mass Assignment Protection:
Combine with $fillable or $guarded:
protected $fillable = ['name', 'email'];
protected $rules = [
'name' => 'required|string',
'email' => 'required|email',
'bio' => 'nullable|string', // Not fillable, but validated if passed
];
API Resource Integration: Validate incoming requests before processing:
public function store(Request $request)
{
$user = new User($request->all());
if ($user->isValid()) {
return response()->json($user->save(), 201);
}
return response()->json($user->errors, 422);
}
Form Requests: Use Ardent alongside Laravel's Form Requests for layered validation:
class StoreUserRequest extends FormRequest
{
public function authorize() { return true; }
public function rules()
{
return [
'name' => 'required',
// Override or complement Ardent rules
];
}
}
public function store(StoreUserRequest $request)
{
$user = new User($request->all());
if ($user->isValid()) {
$user->save();
}
}
Event-Based Validation:
Trigger validation on events (e.g., retrieved, creating):
protected static function boot()
{
parent::boot();
static::retrieved(function ($model) {
$model->validate(); // Re-validate on retrieval
});
}
Testing: Mock validation in tests:
$user = new User(['email' => 'invalid']);
$this->assertFalse($user->isValid());
$this->assertArrayHasKey('email', $user->errors);
Rule Overrides:
FormRequest). Explicitly define all rules in $rules or handle conflicts manually.FormRequest for global rules and Ardent for model-specific rules.Mass Assignment Conflicts:
$fillable. This can lead to unexpected validation errors.$rules or use $guarded.Lazy Validation:
save() is called or validate() is explicitly invoked. Silent failures may occur if validation isn’t triggered.isValid() before save() or use validate() in constructors/initializers.Dynamic Rule Caching:
$rules are evaluated every time validation runs, which can impact performance for complex rules.Error Handling:
protected $messages = [
'email.required' => 'The email field is mandatory.',
];
Database-Level Constraints:
unique) will still trigger if validation passes.unique rules in $rules.Legacy Laravel Support:
Nested Resource Validation:
Post with embedded Comments).Validator manually or extend Ardent with custom logic.Inspect Validation Errors:
$user = new User(['email' => 'invalid']);
$user->validate(); // Trigger validation
dd($user->errors); // Debug errors
Enable Debug Mode:
Set APP_DEBUG=true in .env to see detailed validation error messages.
Log Validation Rules:
Override getRules() to log rules:
public function getRules()
{
\Log::debug('Validation rules:', $this->rules);
return parent::getRules();
}
Check for Silent Failures:
Always verify isValid() before relying on save():
if (!$user->isValid()) {
\Log::error('Validation failed:', $user->errors);
}
Custom Validation Traits: Create reusable validation logic:
trait ValidatesUsername
{
public function validateUsername($attribute, $value, $parameters)
{
if (preg_match('/\d/', $value)) {
return 'Username cannot contain numbers';
}
}
}
Hook into Validation Events:
Extend Ardent’s Validator class:
use LaravelBook\Ardent\Validation\Validator;
class CustomValidator extends Validator
{
protected function runValidation()
{
// Pre-validation logic
$result = parent::runValidation();
// Post-validation logic
return $result;
}
}
Bind it in ArdentServiceProvider:
$this->app->bind('ardent.validator', function () {
return new CustomValidator();
});
Override Default Behavior:
Extend the Ardent trait to modify validation triggers:
trait CustomArdent
{
public function save(array $options = [])
{
if (!$this->isValid()) {
throw new \Exception('Validation failed');
}
return parent::save($options);
}
}
Add Custom Attributes:
Extend validation to support custom attributes (e.g., phone_number):
use LaravelBook\Ardent\Validation\ValidatesWith;
class User extends Model
{
use Ardent, ValidatesWith;
public function validatePhone
How can I help you explore Laravel packages today?