Как получить полиморфный тип отношений при активной загрузке в Laravel Eloquent?

При запросе наличия или отсутствия полиморфных отношений Laravel Eloquent предоставляет whereHasMorph а также whereDoesntHaveMorphметоды, которые действительно полезны для создания запросов, связанных с типами. Но как насчет нетерпеливых нагрузок?

Вот такая ситуация:

Подумайте о трех моделях: App\Photos, App\Videos and App\Blogs.

Все эти три модели можно кормить, что означает, что они имеют полиморфную связь с моделью App\Feed.

Но в то время как модели App \ Photos и App\Videos являются реактивными (имеют полиморфную связь с моделью App\Reactions), модель App\Blogs не имеет этой связи.

Давайте проверим методы:

Приложение \Feed

public function feedable() {
    return $this->morphTo();
}

Приложение \ Реакции

public function reactable() {
    return $this->morphTo();
}

Приложение \ Фото

public function feed() {
    return $this->morphOne('App\Feed', 'feedable');
}

public function reactions() {
    return $this->morphMany('App\Reactions', 'reactable');
}

Приложение \ Видео

public function feed() {
    return $this->morphOne('App\Feed', 'feedable');
}

public function reactions() {
    return $this->morphMany('App\Reactions', 'reactable');
}

Приложение \ Блоги

public function feed() {
    return $this->morphOne('App\Feed', 'feedable');
}

При запросе фидов из модели App\Feed я также хочу получить количество реакций. Но из-за этой модели App\Blogs нет метода с именемreactions, этот запрос вызывает ошибки.

Как я могу создать такой запрос:

$feeds = Feed::with([
    'feedable' => function($query) {
        // I need to get the feedable_type of the feedable here.
        // module_exists is a custom helper to check if an module is installed and active
        if ($type != 'App\Blogs' && module_exists('Reactions')) {
            $query->withCount('reactions');
        }
    }
])->all();

редактировать

Я попытался упростить свой вопрос, но думаю, мне нужно предоставить дополнительную информацию о приложении.

Приложение представляет собой систему управления контентом (система социальных сетей), для которой сторонние разработчики могут разрабатывать модули. Блоги, Фотографии, Видео, Лента, Реакции, Комментарии, Поделиться и т. Д. - все это разные модули, и они могут быть отключены или удалены владельцами сайта. Поэтому, когда разработчики создают модули, они должны учитывать, что модули Reactions, Coments и т. Д. Могут быть отключены или удалены.

1 ответ

1- В соглашении об именах в Laravel говорится, что модели имеют единственную форму, поэтому вы можете рассмотреть возможность переименования моделей в Photo а также Video так далее..

2- В вашем случае Blog модель не имеет реакций, поэтому вы можете создать type Сфера применения Feed модель как:

public function scopeHasReactions($query)
{
    return $query->whereIn('reactable_type', ['App\Photo', 'App\Video']);
}

3- использование $withCount свойство для подсчета, в Photo модель в примере:

protected $withCount = ['reactions'];

Наконец, вы можете сделать такой запрос:

$feeds = Feed::hasReactions()->get();

$feeds->first()->reactions_count;

Надеюсь это поможет.

Другие вопросы по тегам