You can install the package via composer:
composer require wendelladriel/laravel-expressiveYou can publish the config file with:
php artisan vendor:publish --tag="expressive"Add the IsExpressive trait to models that should convert to typed Expressive objects:
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use WendellAdriel\Expressive\Concerns\IsExpressive;
#[Fillable(['name', 'email', 'role', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable
{
use IsExpressive, Notifiable;
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
public function address(): HasOne
{
return $this->hasOne(Address::class);
}
/**
* @return array<string, string>
*/
protected function casts(): array
{
return [
'role' => UserRole::class,
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
protected function displayName(): Attribute
{
return Attribute::make(
get: fn (): string => "{$this->name} ({$this->role->value})",
);
}
}Generate an Expressive class from a model:
php artisan make:expressive User --model="App\Models\User"Generate classes for discovered models in bulk when you want to scaffold a project at once:
php artisan expressive:generate --path="app/Models"Check generated classes for model drift in CI:
php artisan expressive:sync --allThe generated class will live in App\Expressive by default:
use App\Enums\UserRole;
use App\Expressive\Address;
use App\Expressive\Post;
use App\Models\User as UserModel;
use Carbon\CarbonInterface;
use Illuminate\Support\Collection;
use WendellAdriel\Expressive\Attributes\Relationship;
use WendellAdriel\Expressive\Attributes\Virtual;
use WendellAdriel\Expressive\Expressive;
/**
* @extends Expressive<UserModel>
*/
final class User extends Expressive
{
public ?int $id = null;
public string $name;
public string $email;
public UserRole $role;
public string $password;
public ?string $rememberToken = null;
public ?CarbonInterface $emailVerifiedAt = null;
public ?CarbonInterface $createdAt = null;
public ?CarbonInterface $updatedAt = null;
#[Relationship]
public ?Address $address = null;
/** @var Collection<int, Post>|null */
#[Relationship]
public ?Collection $posts = null;
#[Virtual]
public ?string $displayName = null;
}Loaded relationships are converted recursively. A HasOne relation becomes the related model's Expressive object, and a HasMany relation becomes a Collection of Expressive objects.
Convert models, collections, and builders:
$user = User::findOrFail(1)->expressive(attributes: ['display_name']);$users = User::query()->get()->expressive(relationships: ['posts']);$users = User::query()
->where('active', true)
->expressive(relationships: ['posts']);Access the full documentation here.
Please see the changelog for more information on what has changed recently.
Thank you for considering contributing to Expressive! You can read the contribution guide here.
Please review our security policy on how to report security vulnerabilities.
Expressive is open-sourced software licensed under the MIT license.
