Laravel 4: Как применить условие WHERE ко всем запросам класса Eloquent?

Я пытаюсь реализовать "одобренное" состояние для таблицы, которую я имею, это довольно просто, в принципе, если столбец одобрения строки равен 1, эта строка должна быть восстановлена, в противном случае это не должно быть.

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

Как я могу это сделать? Как легко добавить $this->where(..) внутри конструктора дочернего класса Eloquent? Разве это не повлияло бы на другие операции CRUD? например, не обновлять неутвержденную строку?

Ответ 1

Ближайшая вещь, которую я нашел, Яркая область запроса.

Несмотря на то, что это требует незначительных изменений в моем коде (prefixing queries), он все равно дает мне то, что я ищу с большой гибкостью.

Вот пример:

Создайте функцию внутри дочернего класса Eloquent:

class Post extends Eloquent {

    public function scopeApproved($query)
    {
        return $query->where('approved', '=', 1/*true*/);
    }

}

Затем просто используйте его следующим образом:

$approvedPosts = Post::approved()-><whatever_queries_you_have_here>;

Работает отлично. Никаких уродливых повторных вызовов функции WHERE. легко модифицировать. Намного легче читать (approved() имеет гораздо больше смысла, чем where('approved', '=', 1))

Ответ 2

Вы можете переопределить основной запрос, только для модели Post, например

class Post extends Eloquent
{
    protected static $_allowUnapprovedPosts = false;
    public function newQuery()
    {
        $query = parent::newQuery();
        if(! static::$_allowUnapprovedPosts)
        {
            $query->where('approved', '=', 1);
        }
        else{
            static::$_allowUnapprovedPosts = false;
        }
        return $query;
    }

    // call this if you need unapproved posts as well
    public static function allowUnapprovedPosts()
    {
        static::$_allowUnapprovedPosts = true;
        return new static;
    }
}

Теперь просто используйте что угодно, но неутвержденные пользователи не будут отображаться в результате.

$approvedPosts = Post::where('title',  'like', '%Hello%');

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

$approvedPosts = Post::allowUnapprovedPosts()->where('title',  'like', '%Hello%');

Обновление:

Так как Laravel теперь предоставляет Глобальные области запросов, используйте вместо этого хакерского решения уведомление о дате ответа, оно слишком старое и теперь многое изменилось.