#php #laravel #eloquent
#php #laravel #красноречивый
Вопрос:
Вот мой UserController @getIndex, он выводит несколько пользователей и все количество пользователей.
$name = Input::get('name');
$page = Input::get('page');
$limit = Input::get('limit');
$users = User::where('name', 'like', '%'.$name.'%')
->orderBy('created_at', 'desc')
->skip($limit*$page)->take($limit)
->get();
return array(
'rows'=>$users->toArray(),
'results'=>User::where('name', 'like', '%'.$name.'%')->count(),
);
Есть ли какой-либо способ повторно использовать часть ‘where ()’, чтобы мне не приходилось повторять себя?
Ответ №1:
Вы можете использовать области запросов, чтобы не повторяться:
//app/models/User.php
public function scopeFilterName($query, $name) {
return $query->where('name', 'like', '%'.$name.'%');
}
///////////////////////////
//in the controller
$name = Input::get('name');
$page = Input::get('page');
$limit = Input::get('limit');
$users = User::filterName($name)
->orderBy('created_at', 'desc')
->skip($limit*$page)->take($limit)
->get();
return array(
'rows'=>$users->toArray(),
'results'=>User::filterName($name)->count(),
);
Комментарии:
1. Спасибо, scope — хороший способ сделать это. Но я думаю, что область видимости следует использовать каким-то более «распространенным» способом, таким как «scopeFemale» или «scopeOld». Этот контроллер отвечает на панель администратора, для других ресурсов, таких как «порядок», фильтры сложнее, это только для фильтра сетки администратора, используемого только в этом действии, так есть ли какой-нибудь удобный способ?
2. Области видимости являются рекомендуемым и, на мой взгляд, самым простым способом достижения этого подхода. Что я могу придумать, так это использование метода boot() в событиях модели и установка там условного предложения where, но я не пробовал, и даже если бы это удалось, это наверняка было бы сложнее. laravel.com/docs/eloquent#model-events
Ответ №2:
Не очень удобный способ, но он даст вам представление о том, как работает Builder:
$query = User::where('name', 'like', "%{$name}%");
$anotherQuery = clone $query;
$query->orderBy('created_at', 'desc') // you can use latest() method for this btw
->skip( 5 ) // sets OFFSET 5
->take( 10 ) // sets LIMIT 10
->get();
Теперь эти предложения остаются в сборщике, поэтому это вернет null:
$query->count();
из-за этого OFFSET 5
Таким образом, вы можете использовать:
$anotherQuery->count();
или:
$query->skip(0)->take(9999);
или даже менее удобно:
$query->getQuery() // get the base Query Builder object
->limit = null;
$query->getQuery()->offset = null;
И просто примечание — я не согласен, что scope
это здесь не подходит, я бы использовал это на самом деле.
Комментарии:
1. Это очень близко к тому, что я хочу… Если я использую область видимости для этого сценария, это означает, что для большинства моделей будет функция ScopeFilter(diffrentArgs)?
2. Область видимости работает только для модели, в которой она определена. Это просто удобная функция DRY для обычных задач.
filterName($name)
,male()
,recentlyUpdated()
и т.д. Вы можете определить его так, как вам удобно, это всего лишь набор ограничений запроса.