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

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

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

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

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

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

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

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

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();

Изменить

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

Приложение представляет собой систему управления контентом (систему социальной сети), для которой сторонние разработчики могут разрабатывать модули. Блоги, фотографии, видео, лента, реакции, комментарии, общий доступ и т. д. — все это разные модули, которые могут быть отключены или удалены владельцами сайта. Поэтому, когда разработчики создают модули, они должны учитывать, что модули «Реакции», «Комментарии» и т. д. могут быть отключены или удалены.


person Hüseyin Dursun    schedule 24.09.2019    source источник


Ответы (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;

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

person Yamen Ashraf    schedule 24.09.2019
comment
Спасибо за Ваш ответ. Я только что обновил свой вопрос в соответствии с вашим ответом. Пожалуйста, проверьте еще раз. 1. Различные модули могут иметь модели фото, видео и т. д. 2. Будут отображены все фиды независимо от того, являются ли они реактивными или нет. Поэтому я хочу получить не только реактивные, но и нереактивные. 3. Если владелец сайта отключит или удалит модуль «Реакции», это вызовет ошибку. - person Hüseyin Dursun; 24.09.2019
comment
Вы можете подумать о том, чтобы добавить свойство response_count в модель Blog со значением 0 и скрыть его в представлении. - person Yamen Ashraf; 24.09.2019