2016-01-06 5 views
4

я использую Laravel 5.2 для моего проекта, я просто реализовать локальную область (давайте использовать Laravel DOCS пример для простоты - https://laravel.com/docs/master/eloquent#local-scopes)Laravel отрицать локальную область видимости

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class User extends Model 
{ 
    /** 
    * Scope a query to only include popular users. 
    * 
    * @return \Illuminate\Database\Eloquent\Builder 
    */ 
    public function scopePopular($query) 
    { 
     return $query->where('votes', '>', 100); 
    } 

} 

Я называю:

$users = App\User::popular()->get(); 

И это работает как шарм.

Можно ли назвать отрицание области?

$users = App\User::Notpopular()->get(); 

Или мне нужно вручную выполнить отрицание указанной области? Если это лучший способ сделать это?

Заранее благодарю вас!

ответ

3

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

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

public function scopeNotPopular($query) { 
    $query->whereNotIn($this->getKeyName(), function($q) { 
    $q->select($this->getKeyName())->from($this->getTable()); 
    $this->scopePopular($q); 
    }); 
} 

Этого код использует whereNotIn ограничения применять отрицание ограничения из другой области. Это позволит вам повторно использовать логику ограничений вместо реализации исходных и отрицательных версий в двух разных местах. Хотя этот объем кода кажется довольно накладным с областью примера из документов, он имеет больше смысла с более сложными ограничениями.

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

1

Я думаю, что вам нужно реализовать вручную, потому что Laravel не будет «отрицать» автоматически.

Что вы можете сделать, это использовать динамический запрос Область применение: https://laravel.com/docs/5.0/eloquent#query-scopes

Таким образом, в динамических запросах Скоупса, вы можете передать дополнительные параметры, и один из них может быть, если необходимо получить наиболее популярные человек или менее популярные.

+0

Конструктор запросов мог бы сделать что-то вроде этого: scope Где популярно> 100, если я отрицаю условие, в котором предложение where будет NOT (популярным> 100) – eldblz

2

Я использую этот фрагмент кода для областей с отрицанием.

public function scopePublished($query, $negate = false) { 
    return ($negate ? $query->where('published', false) : $query->where('published', true)); 
} 

Теперь, если я просто хочу, опубликованных записей я называю $post->published()... Я хочу, чтобы все неопубликованные записи я называю $post->published(true)...


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

public function scopePublished($query, $override = true) { 
    return $query->where('published', $override); 
} 

опубликованные записи: $post->published()...
неопубликованные записи: $post->published(false)...

+0

Отличное решение! – naneri

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