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 теперь предоставляет Глобальные области запросов, используйте вместо этого хакерского решения уведомление о дате ответа, оно слишком старое и теперь многое изменилось.