ларавель красноречив с конфликтом и присоединяется к нему

#laravel #eloquent

Вопрос:

Я совсем новичок в Ларавеле… У меня есть таблица сообщений, которая связана со статьями и таблицами пользователей. В контроллере я либо получаю все сообщения, соответствующие критериям поиска, либо получаю все сообщения. В обоих случаях я узнал, как добавлять связанные поля в коллекцию $posts.

 // get all posts matching criteria
if (request('search') amp;amp; request('search') != '') {
    $posts = Post::orderBy($orderBySortField,$sortOrder)
        ->with(['user:id,name','article:id,title'])
        ->where('post','like','%'.request('search').'%')
        ->join('users', 'posts.user_id', '=', 'users.id')
        ->orWhere('users.name','like','%'.request('search').'%')
        ->join('articles', 'posts.article_id', '=', 'articles.id')
        ->orWhere('articles.title','like','%'.request('search').'%')
        ->get();
// get all posts
} else {
    $posts = Post::orderBy($orderBySortField,$sortOrder)
        ->with(['user:id,name','article:id,title'])
        ->get(); 
}

// add related fields
foreach ($posts as $post) {
    $post->title = '['.$post->article->title.']';
    $post->user = '['.$post->user->name.']';
}
 

Когда я получаю все сообщения, соответствующие поля отображаются правильно в списке, отображаемом на странице просмотра.

Однако, если я ищу имя конкретного пользователя, я получаю список, в котором $posts->пользователь неверно связан.

Я мог бы понять это, отобразив последние запросы.

Для всех сообщений:

 select * from `posts` order by `posts`.`id` desc
select `id`, `name` from `users` where `users`.`id` in (1, 11)
select `id`, `title` from `articles` where `articles`.`id` in (1)
 

Для сообщений, написанных пользователем ‘paul’ (идентификатор пользователя = 1):

 select * from `posts` inner join `users` on `posts`.`user_id` = `users`.`id` inner join `articles` on `posts`.`article_id` = `articles`.`id` where `post` like ? or `users`.`name` like ? or `articles`.`title` like ? order by `posts`.`id` desc [where ? = %paul% %paul% %paul% ]
select `id`, `name` from `users` where `users`.`id` in (11)
select `id`, `title` from `articles` where `articles`.`id` in (1)
 

Так почему же последние запросы Laravel ищут идентификатор пользователя = 11, который является другим пользователем?

Я делаю что-то не так?

Ответ №1:

Измените код соединения, где

 // get all posts matching criteria
if (request('search') amp;amp; request('search') != '') {
    $search = request('search');
    $posts = Post::orderBy($orderBySortField,$sortOrder)
        ->with(['user:id,name','article:id,title'])
        ->where('post','like','%'.$search.'%')
        ->orWhereHas('user', function($userQuery) use($search){
            $userQuery->Where('users.name','like','%'.$search.'%');
        })
        ->orWhereHas('article', function($articleQuery) use($search){
            $articleQuery->Where('articles.title','like','%'.$search.'%');
        })
        ->get();
}
 

Комментарии:

1. Идеально! Спасибо @N69S

Ответ №2:

Если у вас есть отношение «определить модель», вам не нужно использовать join его в своем запросе, просто используйте with функцию.

Используя эти два, вы создаете дубликаты данных, поэтому вы получаете incorrectly related ошибку.

Комментарии:

1. на самом деле нет, with метод выполняет второй отдельный запрос после результата первого. Он whereHas скомпилирован в основном запросе.