Closed Nvironmental closed 5 years ago
Hi,
No, there's no such component in the plugin. You can probably go through albums
in AlbumList component accessing $album->photos
directly. Though photos aren't eager-loaded with albums by default. So you should add a hook like onRun()
to where you use a component, and then try to eager-load all photos on albums manually to avoid N+1 queries problem.
Or feel free to PR a new component :)
Closing it for now, please reopen if any further questions.
Hi Graker,
I am not able to crack this,
No, there's no such component in the plugin. You can probably go through
albums
in AlbumList component accessing$album->photos
directly. Though photos aren't eager-loaded with albums by default. So you should add a hook likeonRun()
to where you use a component, and then try to eager-load all photos on albums manually to avoid N+1 queries problem.
Can you please guide me more. Please. Thanks
@Nvironmental ,
I can take a peek if you elaborate on what exactly you're doing (code samples included) and what exactly doesn't work as expected (error messages/behaviour description included).
Hi Graker attaching snaps of code here
Not getting any errors but not getting any results either.
$album->photos = $album->photos->getThumb( $this->property('thumbWidth'), $this->property('thumbHeight'), ['mode' => $this->property('thumbMode')] );
Tried this but it gives an error of getThumb doesn't exist.
This:
$album->photos->getThumb( $this->property('thumbWidth'))
is wrong: photos
is an array (collection, to be exact) so you have to go over it with foreach
. Try to remove all your changes and just go over photos
right in your template (like it is done in single album component).
If that works, try to insert $albums->load('photos')
in onRun()
instead of all code you have in the first screen.
If that doesn't work, post code samples and we'll look into it.
P.S. If you don't mind, please try to insert code between triple backticks instead of making screenshots so I could copy it.
Hi Graker, apologies for not being mindful about the backticks for pasting code.
tried the following
==
function onRun()
{
$albums->load('photos');
}
==
{% set album = photoAlbum.album %}
<div class="albums-list row">
{% for album in albumList.albums %}
<div class="album-photos row">
{% for photo in album.photos %}
<div class="photo col-xs-12 col-sm-6 col-md-4 col-lg-3">
<a href="{{ photo.url }}"><img
data-src="{{ photo.thumb }}"
src="{{ photo.thumb }}"
alt="{{ photo.title }}"
title="{{ photo.title }}"
style="max-width: 100%" />
</a>
<a href="{{ photo.url }}"><strong>{{ photo.title }}</strong></a>
</div>
{% else %}
<div class="col-xs-12 no-data">Album doesn't have any photos yet</div>
{% endfor %}
</div>
<div class="album-preview col-xs-12 col-sm-6 col-md-4 col-lg-3">
<h3><a href="{{ album.url }}">{{ album.title }}</a></h3>
<a href="{{ album.url }}">
<img
data-src="{{ album.latestPhoto.thumb }}"
src="{{ album.latestPhoto.thumb }}"
style="max-width: 100%" />
</a>
Created on {{ album.created_at|date('M d, Y') }}
{{ album.photo_count }} images
</div>
{% else %}
<div class="col-xs-12 no-data">You have not created any albums yet</div>
{% endfor %}
</div>
This does loop over the photos and gives me the titles of my photos(wherever they exist) [attached a reference screenshot]
But fails to load the path/url of the photos
Also tried to use {{album.photos}}
which returns
{"id":67,"user_id":null,"album_id":1,"title":"Raj Mahal Complex","description":"","created_at":"2019-02-11 13:03:39","updated_at":"2019-02-13 05:44:55","sort_order":67,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":66,"user_id":null,"album_id":1,"title":"Mahal Complex","description":"","created_at":"2019-02-11 13:03:39","updated_at":"2019-02-13 05:44:27","sort_order":66,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":65,"user_id":null,"album_id":1,"title":"Raj Mahal & Ruins","description":"","created_at":"2019-02-11 13:03:39","updated_at":"2019-02-13 05:43:54","sort_order":65,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":64,"user_id":null,"album_id":1,"title":"Cenotaphs","description":"","created_at":"2019-02-11 13:03:39","updated_at":"2019-02-13 05:43:06","sort_order":64,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":63,"user_id":null,"album_id":1,"title":"Cenotaphs","description":"","created_at":"2019-02-11 13:03:38","updated_at":"2019-02-13 05:42:28","sort_order":63,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":62,"user_id":null,"album_id":1,"title":"Orchha","description":"","created_at":"2019-02-11 13:03:38","updated_at":"2019-02-12 19:08:07","sort_order":62,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""}]
So it does loop over photos in the album and fetches the fields set for it except the path or url of the photo
Let me know how to proceed
Yeah, I forgot that image
file relation is not loaded automatically when photo
model is loaded.
Try to replace
function onRun()
{
$albums->load('photos');
}
with
function onRun()
{
$albums->load('photos', 'photos.image');
}
It also could be 'photos.images'
, try both :)
Hi Graker,
tried
function onRun()
{
$albums->load('photos', 'photos.image');
}
and
function onRun()
{
$albums->load('photos', 'photos.images');
}
But no luck, got the same output as before with no file path or url:
{"id":67,"user_id":null,"album_id":1,"title":"Raj Mahal Complex","description":"","created_at":"2019-02-11 13:03:39","updated_at":"2019-02-13 05:44:55","sort_order":67,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":66,"user_id":null,"album_id":1,"title":"Mahal Complex","description":"","created_at":"2019-02-11 13:03:39","updated_at":"2019-02-13 05:44:27","sort_order":66,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":65,"user_id":null,"album_id":1,"title":"Raj Mahal & Ruins","description":"","created_at":"2019-02-11 13:03:39","updated_at":"2019-02-13 05:43:54","sort_order":65,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":64,"user_id":null,"album_id":1,"title":"Cenotaphs","description":"","created_at":"2019-02-11 13:03:39","updated_at":"2019-02-13 05:43:06","sort_order":64,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":63,"user_id":null,"album_id":1,"title":"Cenotaphs","description":"","created_at":"2019-02-11 13:03:38","updated_at":"2019-02-13 05:42:28","sort_order":63,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""},{"id":62,"user_id":null,"album_id":1,"title":"Orchha","description":"","created_at":"2019-02-11 13:03:38","updated_at":"2019-02-12 19:08:07","sort_order":62,"photo_location":"Tikamgarh, Madhya Pradesh","photo_latitude":"","photo_longitude":""}]
Was wondering since, we are getting id
for each photo in the album, could there be a way to fetch it via that method.
Sincere thanks for your time and help on this :)
It's worth also trying just $albums->load('photos.image');
but I was sure one of those two should have worked.
Yes, off course you can fetch images by id, but it would be very ineffective to run a query to fetch each image. Images should be eager-loaded, I just don't see yet why they are not. Maybe because they are related using October attachment and not original hasOne/belongsToOne.
I think it's also worth to try this:
function onRun()
{
$albums->load(['photos' => function ($query) {
$query->with('image');
}]);
}
Also note that even if it works and attached image will be loaded, you shouldn't access thumbs as {{ photo.thumb }}
because that thumb
is created in the component's prepareAlbums()
method and it is't happening for photos you've just loaded. So I believe you should access your image' thumb like this:
<img src="{{ photo.image.thumb(100, 100, auto) }}"/>
Hi Graker,
Thanks for your incredible help and support. I was finally able to crack this using
{% for album in albumList.albums %}
{% for photo in album.photos %}
<img src="{{ photo.image.path() }}"/>
{% endfor %}
{% endfor %}
On side note: Even if we do not put onRun()
code for eager loading, we still get all the photos for that album
Thanks once again :)
Hi @Nvironmental ,
It does because Laravel lazy-loads each relation when you're accessing it. But it leads to running as much DB queries as there are photos. So if you'd install a debugbar and inspect DB queries made for the request, I believe you'd see N queries of photos table and N queries of images table where N is overall amount of photos. And if I wrote that last sample of eager-loading code correctly, running with it in place would show exactly 1 query of photos and 1 query of images.
So I'd recommend to keep eager-loading code for better performance (that is if it works).
Absolutely! Thanks for your inputs 👍 Cheers 🥂
Hi Graker,
Wanted to know if there is a way to output all the albums with all the photos in it. Currently I can only output list of Albums and one complete album set at a time using its slug (I could add this component multiple times with individuals album slug but this wont scale once you have large number of albums).
Thanks