Условия запроса кэша Laravel Eloquent

#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() и т.д. Вы можете определить его так, как вам удобно, это всего лишь набор ограничений запроса.