I am uploading employee images to a report system built on Laravel, when i try to get the creator of a report comment line i am trying to bring back with it the employee picture. These pictures are stored in the database using the public path link. So when i convert it to the storage path using Storage::url() function i should get the storage link ready to display the image.
but this foreach loop is causing the /storage/ part of the path to be repeated inside the string for as many times the foreach loop runs.
any idea what might be going on?
this is my foreach loop:
foreach($report->lines as $line) {
if($line->creator->employee->picture) {
$line->creator->employee->picture = Storage::url($line->creator->employee->picture);
}
}
creator is the relationship between user and report, employee is the profile of the user as an employee in the system, and the employee has a picture.
when I view the response data, I get this:
/storage//storage//storage//storage//storage//storage//storage//storage//storage/images/b9570720-bd02-4e66-957d-93574ad753b6.jpg
2
Answers
Thank you Erik Woods and miken32 you were both correct, I was under the impression that once you get the collection, that collection works more like an array, and has objects and relationships that are independent from each other so one line creator was different from another even when being the same id. I tested and learned that if you modify the "employee" of one line, where that employee is the same, that get's changed too, I though this only happened until you saved the changes a save().
What I ended up doing is this:
I am checking to see if the picture has already been converted to storage, before applying the change.
Any comments on this approach will be greatly welcome.
The fact that you are assigning the transformed value right back to
$line->creator->employee->picture
looks like the culprit and an anti-pattern: the employee object’s "picture" field will be assigned a value that isn’t what is coming from the database.You could avoid this by doing the transform to a URL where the value used (e.g. use
Storage::url(...)
in a blade file if that is where it is displayed) rather than in this loop. That avoids assigning the value back to the model, as it just uses the transform at the time of output.You could also set a new property on the employee during this loop (e.g.
$line->creator->employee->picture_url = Storage::url(...)
) and then render that instead of changing the value ofpicture
.Alternatively you could just strip
/storage/
from the input:Storage::url(Str::replaceFirst('/storage/', '/', $line->creator->employee->picture)));
. But this is still assigning a value topicture
which doesn’t seem like a good plan because your employee object is being changed for the sake of presentation.