petrelli / scoped-controller
一个非常简单的控制器,根据URL参数自动调用作用域
Requires
- php: ^7.0
- laravel/framework: ~5.6|~5.7|~5.8|^6.0|^7.0
This package is not auto-updated.
Last update: 2024-09-28 14:58:12 UTC
README
Scoped Controller是一个非常简单的Laravel包(<80行代码),允许您通过根据请求参数执行作用域来构建查询并清理控制器。
灵感来源于Ruby on Rails gem Has Scope。
安装
只需将其包含在您的composer.json文件中
composer require petrelli/scoped-controller
或者添加
"petrelli/scoped-controller": "0.9.*"
然后运行composer update。
基本用法
假设我们有一个Book模型,它有两个过滤器:按年份和按作者。
URL参数可能看起来像以下这样
# Get books filtered by year == 2020
/books?byYear=2020
# Get books filtered by author == cortazar
/books?byAuthor=cortazar
# Get books filtered by year and author
/books?byYear=1961&byAuthor=borges
步骤
-
创建您的控制器,并确保继承自
Petrelli\ScopedController\BaseController。 -
使用
$entity变量定义将持有您的集合的类。通常是一个Eloquent模型,但可以是任何可以响应作用域的类。
protected $entity = Book::class;
- 现在定义
$scopes变量为一个数组,遵循以下模式:[ URLparameter => scopeName, .... ]
use Petrelli\ScopedController\BaseController; class EventsController extends BaseController { // Here as an example we have two scopes: year and author. // They will be called if we receive the parameters // byYear and byAuthor respectively. protected $scopes = [ 'byYear' => 'year', 'byAuthor' => 'author', ]; }
- 现在要获取一个筛选后的集合,只需调用
$this->collection()。您可以使用任何可用的函数。如果使用Eloquent,您可以使用get()、paginate(...)或您需要的任何链式方法。
$items = $this->collection()->get(); $items = $this->collection()->paginate(static::PER_PAGE);
自定义作用域链
我们提供了一个名为beginOfAssociationChain()的控制器函数,您可以选择重载。在那里,我们构建将应用所有作用域的基本查询。
例如
protected function beginOfAssociationChain() { return Book::published()->where('library', 'NYC'); }
在这里,每次我们像之前描述的那样调用$this->collection()时,我们将执行published()作用域,并且还会过滤出'library'是'NYC'的书籍。
$items = $this->collection()->get(); $items = $this->collection()->paginate(static::PER_PAGE);
手动应用作用域
我们提供了一个名为applyScopes($query)的函数,以防您想手动将作用域应用于查询。始终,触发哪个作用域取决于请求参数。
// Controller function public function index() { $items = $this->applyScopes(Book::query())->get(); }
额外功能
具有多值参数的作用域
如果您需要定义一个多值参数,请将其作为数组传递,并定义以下作用域
// Here as an example we have two scopes: year and author. // They will be called if we receive the parameters // byYear and byAuthor respectively. protected $scopes = [ 'byYear' => 'year', 'byAuthor' => 'author', 'sortBy' => ['sort_by' ['field', 'direction']], ];
将作用域定义为数组将允许您从URL作为数组传递多个参数给它。
作用域在动作中的应用
# Get books filtered by year = 2018 and sorted by author in alphabetical order
/books?byYear=2018&sortBy['field']=author&sortBy['direction']=asc
# Get books filtered by author = borges and sorted by date
/books?byAuthor=borges&sortBy['field']=date&sortBy['direction']=desc
您应该明白了。作用域只是一个简单的两个参数元素。
public function scopeSortBy($query, $value, $direction = 'asc')
{
//...
}
当然,您可以将它推广到使用任何数量的参数。只需将其添加到$scopes定义中即可。
检查是否存在任何过滤器
常见用例,如果您需要检查是否存在任何作用域
// Returns true/false $this->hasAnyScope()
为不同的动作使用特定的作用域
因为$this->collection()返回一个查询构建器(例如,当使用Eloquent时),您可以像平时一样保持链式方法和作用域
public function index() { // Return Books triggering defined scopes $items = $this->collection()->get(); } public function indexBestSellers() { // Return Books triggering defined scopes + bestSeller scope $items = $this->collection()->bestSeller()->get(); }
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。