2016-06-14 4 views
0

Вопрос. Как я могу использовать красноречив, чтобы произвести этот запрос:Laravel: join Eloquent models

ВЫБЕРИТЕ campaigns.name, users.name из кампаний LEFT JOIN пользователей на campaigns.gamemaster_id = users.id где campaigns.status = 1

Кампании

id gamemaster_id name  status 
1 1    campaign1 1 
2 2    campaign2 1 

Пользователи

id name 
1 rick 
2 bob 

Результат

id gamemaster_id name  status gamemaster_name 
1 1    campaign1 1  rick 
2 2    campaign2 1  bob 

модель кампании

class Campaign extends Model 
{ 
    public function gamemaster() 
    { 
     return $this->belongsTo('App\User', 'gamemaster_id'); 
    } 
} 

Моя попытка сделать красноречивый, но это не удается:

$result = Campaign::where('status', '=', 1)->with('gamemaster')->select('name')->orderBy('users.updated_at', 'desc')->get(); 

ответ

0

Вы можете сделать это двумя способами, первый с помощью конструктора запросов,

$campaigns = DB::table('campaigns')->leftJoin('users', 'campaigns.gamemaster_id', '=', 'users.id') 
      ->select(['campaigns.name as name', 'users.name as gamemaster_name']) 
      ->where('campaigns.status', '=', 1) 
      ->orderBy('users.updated_at', 'desc') 
      ->get(); 

И с жадным загрузки, вы можете получить кампании, как показано ниже. Однако для сортировки по свойству отношения вам нужен другой уровень, который не так просто реализовать.

$campaigns = Campaign::where('status', '=', 1)->with(['gamemaster' => function($query){ 
    $query->select(['id', 'name']); 
}]->select('id', 'gamemaster_id', 'name')->get(); 

Но вы можете использовать функции сбора легко отсортировать его (Тем не менее, это займет больше времени выполнения)

$campaigns = Campaign::where('status', '=', 1)->with(['gamemaster' => function($query){ 
    $query->select(['id', 'gamemaster_id', 'name', 'updated_at']); 
}]->select('id', 'name')->get()->sortByDesc(function ($campaign) { 
    return $campaign->gamemaster->updated_at; 
}) 
+0

Спасибо. Первый, похоже, работает. Но нетерпевая загрузка дает этот запрос: «выберите' id', 'name' из' campaign' где 'status' =?" Возможно, ему не хватает части соединения? – Olof84

+0

Добро пожаловать, вам не нужно присоединяться, он выбирает gamemasters, где они принадлежат к кампаниям, у которых есть статус 1. Таким образом, запускаются два запроса, сначала выбираются кампании, во-вторых, выбираются пользователи, принадлежащие к этим кампаниям. Получил ли он какие-либо ошибки или показал неожиданные результаты? Следует также отметить, что для того, чтобы заказывать кампании с обновленными пользователями атрибутами, вам нужен еще один уровень, поэтому подход соединения проще. – Burak

+0

Когда я запустил его, он говорит следующее: SQLSTATE [42S22]: Столбец не найден: 1054 Неизвестный столбец «gamemaster_id» в «списке полей» (SQL: выберите 'id',' gamemaster_id', 'name',' updated_at' from 'sh_users' где' sh_users'''' в (0)). Я префикс мой стол sh, в моем фактическом проекте. – Olof84

1

Следующий запрос должен работать:

Campaign::whereStatus(1) 
    ->join('users', 'campaigns.gamemaster_id', '=', 'users.id') 
    ->select('campaigns.name', 'users.name') 
    ->orderBy('users.updated_at', 'desc') 
    ->get() 
+0

Вы имеете в виду: Campaign :: где ('статус '=', 1) -> join ('users', 'campaigns.gamemaster_id', '=', 'users.id') -> select ('campaigns.name', 'users.name') -> get(). Когда я бегу, ничего не возвращается. Hm, возможно ли увидеть только что запущенный SQL? – Olof84

+0

гдеStatus (1) или где ('status', '=', 1) - то же самое. Вы пропустили «после вашего статуса». Если вы просто выполните «Кампания :: whereStatus (1) -> get()», что у вас есть? –

+0

Я вижу, что ваш запрос возвращает 2 имени пользователя, но только это. И запрос выглядит следующим образом: «выберите« campaign'.'name', 'users'.'name' из' campaign' internal join 'users' на' campaign'.'gamemaster_id' = 'users'.'id', где 'campaign'''status' =?" Но у него нет порядка. – Olof84

Смежные вопросы