I'm creating an API with Laravel (Lumen) in which there are objects which contain a field which is a path to a file.
These paths are stored as relative paths in the database but upon returning them to user I have to convert them to absolute urls.
Now I was wondering if there is a convenient way to add a non-persistent field to the model objects. Obviously there are Mutators but they are persisted to the database.
I also have thought of creating an after-middleware which traverses the object tree and converts every path
field it finds but this is not an elegant way.
Here is the final transformation I need:
[
{
"id": 1,
"title": "Some title",
"media": [
{
"id": 435,
"path": "relative/path/to/some/file.ext"
},
{
"id": 436,
"path": "relative/path/to/some/file2.ext"
}
]
}
]
To:
[
{
"id": 1,
"title": "Some title",
"media": [
{
"id": 435,
"url": "http://example.com/relative/path/to/some/file.ext"
},
{
"id": 436,
"url": "http://example.com/relative/path/to/some/file2.ext"
}
]
}
]
Any idea is welcome.
You can use Laravel accessors,
From the Docs:
The original value of the column is passed to the accessor, allowing you to manipulate and return the value.
These are not persisted in the DB but are modified as and when you access them.
For example:
class User extends Model
{
/**
* Get the user's first name.
*
* @param string $value
* @return string
*/
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}
Usage:
$user = App\User::find(1);
$firstName = $user->first_name;
In your use case:
Define an accessor in the Media Model for path attribute.
public function getPathAttribute($value)
{
return storage_path($value);
}
If you need to access the property with a different name (alias):
public function getAliasAttribute()
{
return storage_path($this->attributes['path']);
}
// $model->alias
As @Sapnesh Naik said what you need is a simple accessor like this:
public function getPathAttribute($value)
{
$url = config('relative_url') or env('PATH') or $sthElse;
return $url.$this->attributes['path'];
}