Jamie Jamie - 1 month ago 13
PHP Question

Laravel convert one model instance to collection

I'm using Laravel 5.3 and I'm trying to remove files from a user within a job::

public function handle()
{
//Remove all files from a message
$this->files->map(function($file) {
$path = $file->getPath();

if(Storage::disk('s3')->exists($path))
{
Storage::disk('s3')->delete($path);
if(!Storage::disk('s3')->exists($path))
{
$attachment = File::find($file->id);
$attachment->delete();
}
}
});
}


So this is working for
collections
. But how do I get this to work when I pass
one
model instance?

Answer

First, as the algorithm you want apply to the collection's elements or the Eloquent model is the same, move it in a private method as follows:

private _removeFilesFromMessage($file) {
    $path = $file->getPath();

    if(Storage::disk('s3')->exists($path))
    {
        Storage::disk('s3')->delete($path);
        if(!Storage::disk('s3')->exists($path))
        {
            $attachment = File::find($file->id);
            $attachment->delete();
        }
    }
}

Then modify the handle method like this:

public function handle()
{
    if($this->files instanceof Illuminate\Database\Eloquent\Collection) {
        //Remove all files from a message
        $this->files->map($this->_removeFilesFromMessage($file));
    } else {
        $this->_removeFilesFromMessage($this->files);
    }
}

What are we doing here? We're checking if the $this->files instance is an Eloquent Collection and, in case the condition is true, we use the _removeFilesFromMessage as a callback for the map method. Otherwise (I am assuming that the $this->files contains an Eloquent Model instance) the _removeFilesFromMessage method is called and the model is passed.

I think this code is a good start for your needings.

edit

As the title of this question is partially different from what you have asked... for a matter of completion:

You can create Laravel Collections with the collect() method, as described in the Laravel 5.3 official doc