2014-10-02 4 views
0

Создание многоязычного сайта с резервным вариантом на английском языке.Laravel eloquent, сменить запрос, если нет результатов

У меня есть таблица "языки"

__________________ 
|language | text | 
------------------ 
| "EN" | "good" | 
------------------ 
| "NL" | "goed" | 
------------------ 

Мой красноречивым запрос в контроллере:

Languages::language('EN')->take(1)->get(); 

В Типовых языках я функция Области применения:

public function scopeLanguage($query, $language) 
{ 
    $query->where('language', '=', $language); 
} 

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

Languages::language('DE')->take(1)->get(); 

не возвращает никаких результатов, но я хочу иметь запасной вариант на «EN»

я попытался вещи, как:

public function scopeLanguage($query, $language) 
{ 
    $query->where('language', '=', $language); 
    if ($query->count() > 0) { 
     return $query; 
    } else { 
     return $query->where('language', '=', "EN"); 
    } 
} 

без удачи, кажется, что это добавляет новый, где запрос к существующему. Можно ли удалить/изменить запрос ?. без разрыва цепи (фактическая модель имеет несколько функций, сфера применения)

+0

Попробуйте добавить '-> получить()' в вашей области видимости функции, без выполнения Я предполагаю, что есть нет результата и не учитывается также – Danny

+0

Выполнение этой области означает, что вы проигнорируете другие «wheres», которые вы применяете позже (или области), так что это не так. –

+1

Если он добавляет условие 'where' к запросу, вы можете заменить его на' orWhere', и он будет работать нормально. –

ответ

4

Вы могли бы попробовать с этим:

public function scopeLanguage($query, $language) 
{ 
    $q = clone $query; 

    $q->where('language', '=', $language); 
    if ($q->count() > 0) { 
     return $query->where('language', '=', $language); 
    } else { 
     return $query->where('language', '=', "EN"); 
    } 
} 

Как работает это может быть также немного упрощен

public function scopeLanguage($query, $language) 
{ 
    $q = clone $query; 

    $q->where('language', '=', $language); 
    if ($q->count() == 0) { 
     $language = 'EN'; 
    } 
    return $query->where('language', '=', $language); 
} 
+0

Также приводит к SQL: выберите * из 'languages', где' language' = DE и 'language' = EN limit 1 – 77120

+0

Возможно, вы могли бы клонировать запрос $, но как @ JarekTkaczyk упомянул, что это, вероятно, не решит проблему. –

+0

@ 77120 Ваш запрос ничего не возвращал бы каждый раз. Один ield не может иметь два значения одновременно. –

3

Если вы не хотите нарушать цепочку, которую вы могли бы проверить по отдельному запросу:

public function scopeLanguage($query, $language){ 
    if(!self::where('language',$language)->count()){ 
    $language = 'EN'; 
    } 
    return $query->whereLanguage($language); 
} 
+0

Это решение работает, но я сделал (немного предвзятый) тест и TONS медленнее, чем решение @ MarcinNabiałek. В качестве примера можно использовать основную таблицу 4000rows для таблицы обзора и небольшую (в качестве таблицы языков). Среднее количество раз: Шахта - 0.048372030258179/Решение MarcinNabiałek - 1.0967254638672E-5 –

+0

Проверьте запросы, они должны быть одинаковыми. –

+0

Полезно знать, но, вероятно, одного теста недостаточно, чтобы решить, какой метод быстрее и медленнее. –

0
public function scopeLanguage($query, $language) 
{ 
    $countQuery = clone $query; 
    $countQuery->where('language', '=', $language); 

    if ($countQuery->count() > 0) { 
     return $query->where('language', '=', $language); 
    } else { 
     return $query->where('language', '=', "EN"); 
    } 
} 
1

MySQL конкретных решение:

public function scopeLanguage($query, $language) 
{ 
    $languages = [$language, 'EN']; 

    $query->whereIn('language', $languages); 

    $query->orderByRaw('field(language, ?, ?)', $languages); 
} 

затем вызвать first вместо get:

$query->language('DE')-> .... ->first();