webbundels / models
Webbundels 模型
Requires (Dev)
- orchestra/testbench: ^6.0
README
开发原则
在使用框架之前,了解 Webbundels 的开发原则非常重要,这样您就知道为什么某些事情会按这种方式工作。Webbundels 在扩展的 MVC 架构模式上开发,这一模式将在本章中解释。
Webbundels 不在控制器中放置业务逻辑和从数据库检索数据,而是使用模型服务、业务服务和存储库。每个模型都有一个相应的模型服务和存储库。当需要从数据库中检索数据时,我们要求模型服务来检索,它反过来使用存储库来实际检索。
当请求数据库中的数据时,模型服务负责处理和验证随请求附带的数据(例如,过滤数据),然后再将其发送到存储库。这种方法可以将存储库中从数据库检索数据的逻辑最小化。这正是我们想要的,因为存储库的责任仅是检索数据库中的所需数据并将其返回给模型服务。当存储库将数据库中的数据返回给模型服务时,模型服务负责处理、验证和修改数据,然后再将其展示给请求者。
当控制器需要“容易获取”的数据或想要执行简单的任务(如删除或更新数据库中的记录)时,可以直接在控制器中使用模型服务。然而,当需要更复杂的逻辑时,可以使用业务逻辑服务。可以在业务服务中使用多个模型服务来完成更困难的任务。
用法
本章是对框架所提供的一切的总结。
模型服务
模型服务是所有数据请求都经过的对象。由于并非所有数据请求都需要由模型服务处理,因此在模型服务上调用未存在的所有方法将自动重定向到类属性 'repo' 上设置的存储库。
要创建模型服务,可以使用以下命令
php artisan wb:make:model-service #Modelname
这样,大量的默认代码,如相应的存储库、扩展类等,都会自动设置。
存储库
存储库负责从数据库中检索数据。抽象存储库中提供了很多预定义的方法。每个存储库都扩展了抽象存储库。只要没有特殊查询要求,大部分数据都应该可以通过使用这些预定义方法获取。在我们逐一介绍这些方法之前,我们先解释一下这些方法中使用的参数。
数组 $filters
$filters 参数用于过滤、排序、分组和其他特殊查询扩展。如何进行过滤以及哪些默认过滤可能性是可能的将在下一章“模型”中解释。
数组 $with
当需要将关联模型与请求的模型一起拉取时使用 $with 参数。如何使用它将在下一章“模型”中解释。
整型 $id
此参数是获取 id 为 '$id' 的模型时的默认过滤方法。
数组 $ids
此参数是获取具有在数组 '$ids' 中存在的 id 的模型的默认过滤方法。
数组 $data
此参数用于更新或插入数据。数组 $data 中的数据应该是您想要插入或更新的数据。数组应如下所示
[attribute-1 => value, attribute-2 => value]
以下列出了所有预定义方法。
get(array $filters = [], array $with = [])
获取所有符合数组 '$filters' 条件并与关系 '$with' 相关联的模型。
first(array $filters = [], array $with = [])
获取符合数组 '$filters' 条件并与关系 '$with' 相关联的第一个模型。
getAll(array $with = [])
获取所有与关系 '$with' 相关联的模型。
getById($id, array $with = [])
获取 ID 为 '$id' 且与关系 '$with' 相关联的模型。
getByIds($ids, array $with = [])
获取所有 ID 存在于数组 '$ids' 中的模型。
getByName($name, array $with = [])
获取列名与 '$name' 相同的模型,并具有关系 '$with'。
pluckIds(array $filters = [])
获取符合数组 $filters 条件的模型的所有 ID。
pluck(string $column, array $filters = [])
获取符合数组 '$filters' 条件的模型列 '$column' 的值集合。
pluckWithKeys(string $column, string $key, array $filters = [])
获取一个集合,其中键是列 '$key' 的值,值是列 '$column' 的值,对应于符合数组 '$filters' 的模型。
count(array $filters = [])
获取符合数组 '$filters' 条件的模型数量。
paginate(array $filters = [], array $with = [])
获取符合数组 '$filters' 条件并与关系 '$with' 相关联的所有模型,并进行分页,有关分页的更多阅读请参阅 此处。
increment($column, array $filters = [], $amount = 1)
将列 '$column' 的值增加 '$amount'(默认为 1)对于所有符合数组 '$filters' 条件的模型。
decrement($column, array $filters = [], $amount = 1)
将列 '$column' 的值减少 '$amount'(默认为 1)对于所有符合数组 '$filters' 条件的模型。
store(array $data, array $with = [])
使用数据 '$data' 存储模型,返回具有关系 '$with' 的模型。数组应如下所示
[attribute-1 => value, attribute-2 => value]
storeMany(array $data)
使用数据 '$data' 存储多个模型,返回具有关系 '$with' 的模型。数组应如下所示
[ [attribute-1 => value, attribute-2 => value], // Model-1 [attriute-1 => value, attribute-2 => value] // Model-2 ]
firstOrStore(array $data, array $delayed_data = [])
获取符合过滤器数组 '$data' 的第一个模型,如果不存在,则使用 '$data' 与 '$delayed_data' 结合存储模型。
update($id, array $data, array $with = [])
使用数据 '$data' 更新 ID 为 '$id' 的模型,并返回具有关系 '$with' 的模型。
updateFiltered($filters, array $data, array $with = [])
使用数据 '$data' 更新所有符合过滤器 '$filters' 的模型,并返回所有具有关系 '$with' 的模型。
destroy($id, array $with = [], $forceDelete = false)
删除 ID 为 '$id' 的模型,返回具有关系 '$with' 的模型。如果 forceDelete 为 true,则模型将从数据库中永久删除。
destroyMany(array $ids, $forceDelete = false)
删除所有 ID 存在于数组 '$ids' 中的模型。如果 forceDelete 为 true,则模型将从数据库中永久删除。
forceDestroy($id, array $with = [])
强制删除 ID 为 '$id' 的模型,返回具有关系 '$with' 的模型。
要创建存储库,可以使用以下命令
php artisan wb:make:repository #Modelname
模型
模型在MVC架构中始终按照常规使用。在抽象模型中有两种方法,使过滤和通过过滤器获取关系更加容易。
创建模型可以使用以下命令
php artisan wb:make:model #Modelname
scopeFilter
第一个是scopeFilter($query, $filters)方法,这是一个本地作用域方法。此方法使使用数组进行过滤成为可能,也是用于在仓库中过滤的方法。
按键过滤
有一些预定义的键用于过滤,下面是列表。在这些示例中,您需要将'column'替换为要过滤的列。所有示例都应该是自解释的。
- ['column_is' => value]
- ['column_is_not' => value]
- ['column_is_in' => [value, value]]
- ['column_is_not_in' => [value, value]]
- ['column_is_greater_than' => value]
- ['column_is_not_greater_than' => value]
- ['column_is_greater_or_equal_than' => value]
- ['column_is_not_greater_or_equal_than' => value]
- ['column_is_less_than' => value]
- ['column_is_not_less_than' => value]
- ['column_is_less_or_equal_than' => value]
- ['column_is_not_less_or_equal_than' => value]
- ['take' => value]
- ['skip' => value]
- ['without_scope' => value]
- ['order_by' => value]
- ['order_by_desc' => value]
- ['order_by' => ['order_by_column', 'order_by_colum', 'order_by_desc_column']]
- ['relation' => $filters_array] <- 这与whereHas功能相同
- ['!relation' => $filters_array] <- 这与whereDoesntHave功能相同
按值过滤
除了按键过滤外,还有一个针对数组中值的预定义过滤器。这些是:['with_trashed', 'without_scopes']
自定义过滤器
如果您需要更多一些的功能,并希望将自定义的过滤功能添加到某些模型中,可以通过将'scopeFilter'方法复制到所需模型中来实现。重要的是您必须调用父类的'scopeFilter'方法,否则您将失去默认过滤方法的全部功能。向'Post'模型添加自定义过滤器以获取标题包含特定字符串的所有帖子的示例可以通过以下方式完成
public function scopeFilter($query, $filters = []) { $query = parent::scopeFilter($query, $filters); if (array_key_exists('title_contains', $filters) { $query = $query->where('title', 'like', '%' . $filters['title_contains'] . '%'); } return $query; }
使用此方法,您可以通过以下方式获取标题包含'Webbundels'的所有帖子:
$webbundelsPosts = Post::filter(['title_contains' => 'Webbundels'])->get();
或者,如果您想通过使用模型服务来实现相同的功能,可以这样做
$webbundelsPosts = App::make('PostService')->get(['title_contains' => 'Webbundels']);
scopeWiths
第二个方法是'scopeWith($query, $with)',这也是一个本地作用域方法。这也是在仓库方法中使用'$withs'参数时所使用的方法。此方法与模型中的常规with方法功能相同,除了在尝试使用约束预加载关系时,您可以使用数组作为约束/过滤器。这些与'scopeFilter'方法中的过滤器功能相同,它使用相同的函数进行约束。例如,当尝试获取id为'1'的帖子及其所有在'2019-01-01'之后创建的评论时,您可以这样做
App::make('PostService')->getById(1, ['comments' => ['created_at_is_greater_than' => '2019-01-01']]);
此外,还有计算关系关联数目的可能性。这是通过在关系键之前使用count来完成的。例如,如果我们想执行前面的示例,但不是获取在'2019-01-01'之后创建的评论,而是只想获取评论的数量,可以这样做
$post = App::make('PostService')->getById(1, ['countComments' => ['created_at_is_greater_than' => '2019-01-01']]); echo $post->comments_count;
即使过滤嵌套关系也不是问题。例如,如果你想要获取具有相同评论的相同帖子,并且如果评论的用户ID是'1337',还想获取这些评论的点赞,你可以这样做
$post = App::make('PostService')->getById(1, [ 'comments' => ['created_at_is_greater_than' => '2019-01-01'] 'comments.likes' => ['likes' => ['user_id_is' => 1337]] ]);
或者如果你想进一步指定,只想获取那些获得用户ID '1337' 点赞的评论,并获取这些点赞,我们可以这样做
$post = App::make('PostService')->getById(1, [ 'comments' => [ 'created_at_is_greater_than' => '2019-01-01' 'likes' => ['user_id_is' => 1337] ] 'comments.likes' => ['likes' => ['user_id_is' => 1337]] ]);
模型类
当你想要创建一个新模型时,在大多数情况下,你还需要创建迁移、模型服务、仓库、资源、资源集合,并将模型服务绑定到你的服务容器中。手动创建所有这些文件可能会非常耗时,尤其是在你有新项目并且需要创建很多文件时。要创建所有这些文件,你可以使用以下命令
php artisan wb:make:model-classes #Modelname