Working with files
Working with files
Working with files from your models
The HasFiles trait is the main API surface you interact with day to day. Add it to any Eloquent model (User, Property, Service, Organization) and that model can hold files grouped into named collections (avatar, gallery, documents, and so on). Files attach through a polymorphic relation, so one model can own many collections at once.
use EduLazaro\Laracrate\Concerns\HasFiles; class User extends Authenticatable { use HasFiles; }
Collections are declared in config/laracrate.php (see the Configuration section). You usually do not need to do anything else on the model. If you want per-model tweaks to a collection (a different disk, a different placeholder, a render component), declare the optional $fileCollections property. It is merged recursively over the base config (array_replace_recursive), so you only override the keys you care about:
class User extends Authenticatable { use HasFiles; protected array $fileCollections = [ 'avatar' => [ 'component' => 'user-avatar', 'placeholder' => '/img/default-avatar.png', ], ]; }
Adding files
Use addFile() to append a file to a collection. It accepts an UploadedFile, a local path string, a Binary, or a FileUpload (the value object returned by direct-to-bucket uploads, see the Upload modes section).
$user->addFile($request->file('photo'), 'gallery');
The full signature:
public function addFile( UploadedFile|Binary|FileUpload|string $file, string $collection, array $data = [], array $slots = [], ?Model $creator = null, ?Model $owner = null, ?Folder $folder = null, ): ?File
| Argument | Purpose |
|---|---|
$file |
The upload source: UploadedFile, path string, Binary, or FileUpload. |
$collection |
The collection name, must be declared in config. |
$data |
Per-file attributes (see below). |
$slots |
File slot keys to attach the file to (see the File slots section). |
$creator |
Who created it. Defaults to auth()->user(). |
$owner |
Semantic owner when different from the creator. |
$folder |
A Folder belonging to this same model (see the Folders section). |
The $data array maps to dedicated columns: title, description, category, visibility, label, default, position, plus a metadata key that is stored as-is in the JSON metadata column. Any other key throws InvalidArgumentException, so a typo fails loudly instead of being silently dropped. To store arbitrary data, nest it under metadata.
$user->addFile($request->file('cv'), 'documents', [ 'title' => 'Resume 2026', 'category' => 'application', 'metadata' => ['source' => 'web'], ]);
Processing (variants, previews, text extraction, embeddings) runs asynchronously on the queue after the file is created, so addFile() returns instantly. See the Processing pipeline section.
Replacing a single file
Use setFile() for "one file per collection" cases like an avatar or a logo. It force-deletes every existing file in the collection (and their variants), then adds the new one. Pass null to clear the collection without adding anything.
$user->setFile('avatar', $request->file('avatar')); $user->setFile('avatar', null); // remove the current avatar
public function setFile( string $collection, UploadedFile|Binary|FileUpload|string|null $file, array $data = [], ?Model $creator = null, ?Model $owner = null, ): ?File
Deleting and reordering
$user->deleteFile($file); // soft delete $user->deleteFile($file, forceDelete: true); // also purge the binary now $user->reorderFiles('gallery', [42, 17, 9]); // assigns position 0, 1, 2 by index
reorderFiles() takes the file IDs in the order you want and writes position by array index. It only touches top-level files that belong to this model and collection, so it is safe to drive directly from a drag-and-drop UI.
Defaults
A collection can mark one file as its default (the chosen avatar among several uploads, the cover of a gallery). Set it from the parent model or from the file itself:
$user->setDefaultFile($file); // unsets any other default in the collection, returns the fresh File $file->makeDefault(); // same, called on the File model
Querying files
| Method | Returns | Notes |
|---|---|---|
files(?string $collection = null) |
MorphMany |
Top-level files ordered by position then id. Filter by collection when passed. |
file(string $collection) |
?File |
The default (if any) or otherwise the most recent file in the collection. |
defaultFile(string $collection) |
?File |
Only the file flagged default = true. |
images(?string $collection = null) |
MorphMany |
Files where type = image. |
$avatar = $user->file('avatar'); // single best file $gallery = $user->files('gallery')->get(); // all, in order $photos = $user->images()->get(); // every image across collections
files() and images() return query builders, so you can keep chaining (->where(...), ->paginate(...)). file() and defaultFile() execute and return a File or null.