spatie / laravel-medialibrary

Associate files with Eloquent models
https://spatie.be/docs/laravel-medialibrary
MIT License
5.77k stars 1.07k forks source link

getMedia() Query Issue #949

Closed angryalf closed 6 years ago

angryalf commented 6 years ago

Hi!

I used 6.1 media library and have issue with query be generated :

$job->getMedia();

select * from `media` where `media`.`model_id` in ('681') and `media`.`model_type` = 'App\Models\Job'

MySQL returned an empty result set (i.e. zero rows). (Query took 0.0004 seconds.) this query generated by your library and got 0 results, but if i make this:

select * from `media` where `media`.`model_id` in ('681') and `media`.`model_type` = 'App\\Models\\Job'

got right results Showing rows 0 - 0 (1 total, Query took 0.0005 seconds.)

MySQL: 5.7 PHP: 7.1 Laravel: 5.5 laravel-medialibrary: 6.1

freekmurze commented 6 years ago

I'm having a hard time spotting the difference between the generated query and the one you manually made.

Pretty sure your problem is caused by something on your machine, otherwise issue reports would have flooded in, tests on travis seem to pass too.

sebastiandedeyne commented 6 years ago

Looks like the slashes / double slashes differ, not sure why?

ashwani23 commented 6 years ago

Hi @sebastiandedeyne

Can you please share that what database driver and storage engine are you using?

sebastiandedeyne commented 6 years ago

We're using MySQL with the local storage driver.

phamels commented 6 years ago

Exact same issue with same specifications.

hasMedia() on model returns nothing, making manual query, no problem. Also, $model->hasMedia() returns false.

Models contains: use Spatie\MediaLibrary\HasMedia\HasMediaTrait; use Spatie\MediaLibrary\HasMedia\HasMedia;

implements HasMedia

use HasMediaTrait;

Saving media was not an issue, but can't seem to retrieve it.

phamels commented 6 years ago

Ok, update:

So doing getMedia() returns nothing, but specifying a specific collection does work for example: getMedia('collection')

documentation ftw :-)

flexchar commented 6 years ago

Just to note, came exactly around the same issue. Been digging for a few hours.

I don't know if I'm misusing something or so but the very least I'd expect documentation to point this out. Now it's not even mentioned. https://docs.spatie.be/laravel-medialibrary/v7/basic-usage/retrieving-media :(

Used with comments that belong to post as realationship hasMany. $post->comments[3]->getFirstMedia() returns an empty collection, where as$post->comments[3]->getFirstMediaUrl('comments') returns as expected.

Thanks for the package thou!

audetcameron commented 5 years ago

Having the same issue, I had to pass the collection name to getMedia aka: ->getMedia('mycollectionname')

meletisf commented 5 years ago

Same problem here. It seems like the FQN of a model, when it contains slashes, causes the query to not return any results.

In my case media.model_type = 'App\Evently\Organizer\Models\Organizer' returns nothing but media.model_type = 'App\Evently\Organizer\Models\Organizer' works fine. It seems like an assumption is made that models will always reside inside st the App namespace.

EDIT: Indeed if you pass a collection it does work with the same exact query.

alexdpunkt commented 5 years ago

@meletisf can confirm this. My models reside in App\Models, a simple getMedia() on my models returns an empty collection, whereas getMedia('collection_name') works.

jehkinen commented 5 years ago

why this one is closed? I have MariaDb 10.4 version and have issue with backslashes.

I'm trying to remove Medias as $model->media()->delete(); it produce query like

DELETE media WHERE media.model_id = ? AND media.model_id IS NOT NULL AND media.model_type = 'App\MyModel' but this query returns null because it must be

media.model_type = 'App DOUBLESLASHHERE MyModel', guys how did you solve this issue?

aprdev47 commented 5 years ago

Illuminate \ Database \ QueryException (HY000)

SQLSTATE[HY000]: General error: 2036 (SQL: select * from media where media.model_id = 41 and media.model_id is not null and media.model_type = App\User)

Works fine in my production instance

Having an issue while running it locally

jehkinen commented 5 years ago

It's not a Spatie Library problem, but it because of MariaDB, so for all queries there are needs that all slashes escaped

I solved this issue by changing relation names for morph relation type

    public static function boot()
    {
        parent::boot();
        Relation::morphMap([
          Course::shortClassName() => Course::class,
          User::shortClassName() => User::class,

          CourseHomeworkContent::shortClassName() => CourseHomeworkContent::class,
          CourseLessonContent::shortClassName() => CourseLessonContent::class,
        ]);
    }

    /**
     * Get only class name without namespace
     * @return bool|string
     */
    public static function shortClassName()
    {
        return substr(strrchr(self::class, "\\"), 1);
    }

So when I save my models, it save only model class without namespace, hope it helps to who has the same issues

pathros commented 4 years ago

I also want to confirm that so far in Laravel-medialibrary V8 $mediaItems = $yourModel->getMedia(); returns empty collection.

Like others have already pointed out, you have to specify the collection name, which is in the 'collection_name' column, like so:

$mediaItems = $yourModel->getMedia('collection_name');

So you'll have to figure out how to get the corresponding 'collection name' first.

Anyway, thanks a lot for the package! It saves lots of time and programming lines!

davidnknight commented 4 years ago

Also ended up here from a Google search as baffled as to why ->getMedia(), ->getFirstMedia() and ->getFirstMediaUrl() wouldn't work.

If I returned $model->media, I'd see results, but ->getMedia() would return nothing. However, as many have stated, providing the collection name as a parameter to any of the above three methods works.

I'm not sure if this is intended behaviour but I'm guessing that it's not because surely you'd expect ->getMedia() to return all media irrelevant of collection. Similarly, you'd expect ->getFirstMedia() and ->getFirstMediaUrl() to return the first media, again irrelevant of collection, and passing the collection name as a parameter to any of these three methods obviously just adds ->where('collection_name', $collection_name).

In any case, there's no mention in the documentation that makes any mention that these methods require any parameters passed to them and it implies that they work without any. I would make a pull request to update the documentation but I don't know if it's expected or a bug, as said. Either way, it would be good to have it either fixed of documentation updated as clearly this has been causing confusion since 2018 and it's now 2020.

Max-Hutschenreiter commented 2 years ago

It's expected behavior since you added a specific media collection. getFirstMedia gets the 'default' if not specifically set. But I agree its a little hard to spot.

public function getFirstMedia(string $collectionName = 'default', $filters = []): ?Media

Rub-s commented 2 years ago

I faced this issue. $product->getMedia(); will execute this sql query

select * from 'media' where 'media'.'model_id' in (1) and 'media'.'model_type' = 'App\Models\Product'

This part of the query ... media.model_type = 'App\Models\Product' is missunderstood by a 5.7.33 version MySql.

I guess mysql is escaping the backslashes so it's trying to get records like this string 'App Models Product' (without backslashes). I can't find a clear documentation about this version of MySql.

A quick fix would be to add "NO_BACKSLASH_ESCAPES" to sql_mode variable. sql_mode = other stuff ... NO_BACKSLASH_ESCAPES;