Model HasFiles Trait for Eloquent Models

dev-master 2021-10-26 09:24 UTC

This package is auto-updated.

Last update: 2021-12-26 09:39:19 UTC


Please consider using Spatie Media Library instead.

Model Files

This is still in development, since it was extracted from an existing project some functionality is still being developed and changed.

The tests were linked to multiple Models (will be moved soon).

Author: Tiago Tavares

Made with ❤️ by Cyber-Duck Ltd


Model files provide a simple trait (HasFiles) to be used by your eloquent models.

This trait allows you to define in your model through an array a simple storage configuration:

  • An observer will handle the storage and pruning of files presents in the disk.
  • Another trait is used for methods interacting with the Storage facade.


composer require cyber-duck/model-files --dev


Storing/Saving e.g. from one of your controller:

public function store(Request $request, Company $company) {
    $validatedData = $request->validate([
        'logo' => 'required|image',
    // You can set logo to a string (if it's already stored in the disk)
    // If won't create another file
    $company->logo = $validatedData->logo;

Accessing the file url:


Delete file:

$company = Company::find(1);
$company->deleteFile('logo'); // Deletes and sets the attribute to `null`

@todo delete model also prunes the file

Company::find(1)->delete(); // File will be deleted as well

### Configuration

Make your model implement Storable interface and use the trait HasFiles to your models class.


namespace App;

use Cyberduck\ModelFiles\Storable;
use Cyberduck\ModelFiles\HasFiles;
use Illuminate\Database\Eloquent\Model;

class Company extends Model implements Storable
    use HasFiles;

Define your files on the model:

class Company extends Model implements Storable
    protected $files = [
        'logo' => [
            'disk' => 'public', // Default is 'default'
            'folder' => 'logos', // Default is '/'
            'prunable' => true, // Default is true
        'avatar' => [
            'disk' => 'public',
            'folder' => 'avatars',
            'url' => 'temporary', // available: 'public' (default), 'temporary', 'custom'
            'expiresAt' => '+5 min', (Not implemented yet - for temporary)
        'invoice' => [
            'folder' => 'invoices',
            'url' => 'custom', // The following method will be called: `getUrlInvoice` with the value of the attribute
    public function getUrlInvoice($path) {
        // e.g. `companies/1/invoices/randomGenerated.pdf`
        return route('company.invoice', [$company, $path]);