2013-07-22 1 views
2

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

Laravel 4

У меня есть 2 таблицы:

users table: 
    ->id 
    ->name 


certificats table: 
    ->id 
    ->user_id 
    ->certificate_type 

I`m в настоящее время борются с этим в течение нескольких часов. Последнее, что я попытался было:

$users = User::with(array('certificate' => function($query) 
{ 
    $query->where('type','!=','SL'); 
}))->get(); 

Это дает мне все пользователи, но я пытался получить все пользователи без типа сертификата «SL».

- редактировать: Исследуемый необработанный запрос Spencer7593 ниже работает. Но я не получу красноречивый запрос для работы.

SELECT u.* 
FROM users u 
LEFT 
JOIN certificates c 
ON c.user_id = u.id 
AND c.type = 'SL' 
WHERE c.user_id IS NULL 

Отношения:

public function certificate(){ 
    return $this->hasMany('Certificate'); 
} 

public function certificate(){ 
    return $this->belongsTo('User'); 
} 
+0

Помогает ли это: $ query-> где ('certificate_type', '! =', 'SL'); – Maximus2012

+0

Нет, это не так :(, я также попытался «certificate.type». – mauricehofman

+0

«type» относится к столбцу в таблице сертификатов, поэтому это должно быть правильно. Вы не переопределяете переменную '$ users' где-либо еще это может быть перезаписью этого? И у вас есть соответствующая функция в вашей модели User для связывания ее с сертификатами? – user1669496

ответ

1

SQL, чтобы получить набор результатов вы хотите, довольно просто.

SELECT u.* 
    FROM users u 
    LEFT 
    JOIN certificates c 
    ON c.user_id = u.id 
    AND c.type = 'SL' 
WHERE c.user_id IS NULL 

Это знакомый образец, называемый «анти-соединение». В принципе, это LEFT JOIN ищет подходящие строки, а также строки из users, которые не имеют соответствия, а затем отфильтровывают все строки, которые получили совпадение, и у нас остались строки из users, которые не имеют совпадение.

Трюк будет получать Eloquent для создания этого SQL для вас. Чтобы получить Eloquent, чтобы сделать это, вам нужно сказать красноречивее сделать LEFT JOIN и добавьте ИНЕКЕ,

может быть что-то подобное было бы близко:

->left_join('certificate AS c', function($join){ 
     $join->on('c.user_id','=','user.id'); 
     $join->and_on('c.type','=','SL'); 
    }) 
->where_null('c.user_id') 

Followup

(В интересах тех, кто может не читать комментарии)

Klass Terst (OP), сообщает о синтаксических проблемах при попытке получить «Красноречивый» (в ответе выше): left_join необходимо заменить на leftJoin, и and_on не был признан. (Последнее, возможно, мое изобретение, основанный на используемом в с where, and_where, or_where.)

$users = DB::table('users') 
    ->select('users.id','users.name') 
    ->leftJoin('certificate AS c', function($join){ 
    $join->on('c.user_id','=','user.id'); 
    $join->on('c.type','=','SL'); 
    }) 
    ->where_null('c.user_id'); 
+0

Ваш необработанный запрос работает, но когда я попробую ваше красноречивое решение, я получаю большой объект. Я не знаю, как использовать. чтобы изменить left_join на leftJoin, и and_on не работал (не существует?). Так что я получил это: $ users = DB :: table ('users') -> select ('users.id', 'users.name') \t -> leftJoin ('certificate', function ($ join) { $ join- > на ('certificate.user_id', '=', 'user.id'); $ join-> on ('certificate.type', '! =', 'SL'); }) -> где_null ('certificate.user_id'); dd ($ users); – mauricehofman

+0

@ Klaas Terst: Я ожидаю, что сырой запрос будет работать; это привычный шаблон, называемый «anti-join». В этом случае мы действительно не заинтересованы в возврате каких-либо столбцов из сертификатов; это только возврат столбцов из таблицы users. Я определенно не эксперт с Eloquent; Я просто взял удар в то, что, как я думал, может сгенерировать этот оператор SQL. – spencer7593

+0

@ Klaas Terst: это действительно должен быть тест на равенство «SL», а не тест на неравенство. Вы хотите «маркировать» строки от пользователей, имеющих соответствующую строку «SL». – spencer7593

0

Я считаю, что проблема в ваших отношениях.

Модели

class User extends Eloquent 
{ 
    public function certificates() 
    { 
     return $this->hasMany('Certificate'); 
    } 
} 

class Certificate extends Eloquent 
{ 
    public function user() 
    { 
     return $this->belongsTo('User'); 
    } 
} 

Контроллер

$users = User::with(array('certificates' => function($query) 
{ 
    $query->where('type','!=','SL'); 
}))->get(); 
return View::make('yourView')->with('users',$users); 

Посмотреть

@foreach($users as $user) 
    {{ $user->name }} // User's name 
    @foreach($user->certificates as $certificate) 
     {{ $certificate->certificate_type }} // Certificate type shouldn't be 'SL' 
    @endforeach 
@endforeach 

Я надеюсь, что это помогает!

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

  • Нет связанных вопросов^_^