Правильный способ поиска статей, которые имеют тег в отношении многие ко многим на Eloquent в Laravel - PullRequest
2 голосов
/ 07 июня 2019

У меня есть три таблицы, таблица статей, таблица тегов и промежуточная сводная таблица с именем article_tags, которая содержит только article_id и tag_id, образуя отношение «многие ко многим».

Я хочу написать функцию, которая получает Статью и возвращает коллекцию или запрос со всеми Статьями, которые разделяют хотя бы один тег с полученной Статьей , после того, как я попробовал несколько разных решений, у меня есть это:

public function scopeRelated($query, Article $article)
{
    return $query->whereHas('tags', function ($query) use ($article) {
        // I've tried a bunch of different lines, like just $article->tags
        $query->whereIn('tags', $article->tags->pluck('id'));
    });
}

Возвращает ошибку:

Освещение / База данных / QueryException с сообщением «SQLSTATE [42S22]: Столбец не найден: 1054 Неизвестный столбец« теги »в« выражении where »(SQL: выберите * из articles, где существует (выберите * из tags внутреннее соединение article_tag в tags. id = article_tag. tag_id, где articles. id = article_tag.article_id и tags in (1, 6, 4))) '

Очевидно, Eloquent пытается сопоставить теги со столбцом' tags 'в таблице Articles, который не'не существует.Как правильно спросить, чего я хочу?

Ответы [ 2 ]

2 голосов
/ 07 июня 2019

Используйте tag_id, чтобы быть сверхспецифичным с подзапросом:

return $query->whereHas('tags', function ($query) use ($article) {
    $query->whereIn('tag_id', $article->tags->pluck('id'));
});

'id', как предложено в другом ответе, работал для меня в Laravel 5.8 и MySQL 5.7.Возможно, включен определенный строгий режим, или у вас действительно есть столбец id в таблице article_tag, когда он вам не нужен.

Кроме того, не забудьте исключить оригинальную статью изсвязанные результаты!:)

$query
    ->whereHas('tags', function ($query) use ($article) {
        $query->whereIn('tag_id', $article->tags->pluck('id'));
    })
    ->where('id', '<>', $article->id);
1 голос
/ 07 июня 2019

Заменить столбец 'tags' на 'tags.id'. Также, если объект $article не имеет загруженного отношения тегов, я бы предложил $article->tags()->pluck('id'), потому что этот способ eloquent будет запрашивать только идентификаторы статей.

И Акен Робертс прав, вы можете исключить $article из результатов. Я предполагаю, что таблица со статьями называется articles.

Таким образом, запрос будет выглядеть так:

    return $query->whereHas('tags', function ($query) use ($article) {
        $query->whereIn('tags.id', $article->tags()->pluck('id'));
    })->where('articles.id', '<>', $article->id);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...