詹姆斯·阿斯彭斯 / laravel-core-model
一个 Laravel 核心模型层,包含工厂和仓库。
Requires
- illuminate/database: ^5.4
Requires (Dev)
- mockery/mockery: ^0.9.4
- phpunit/phpunit: ^5.3
Suggests
- illuminate/pagination: (Required to paginate the result set (^5.4).)
This package is not auto-updated.
Last update: 2020-01-24 16:41:36 UTC
README
一个用于 Eloquent 模型的仓库、工厂和标准层,提供方便的仓库接口,同时仍然允许完全功能化的、优雅的使用。允许方便的测试和依赖注入,而不会牺牲功能或多功能性。
要求
- Laravel 5.3+
安装
composer require jamesaspence/laravel-core-model
使用
Laracore(Laravel 核心模型)非常容易使用。它与您已经熟悉的 Eloquent 模型完全相同。这意味着您可以使用所有已经熟悉的模型查询。
//First we instantiate the repository $repository = new ModelRepository(); //We pass in the reference to the model class //so we can query it $repository->setModel(User::class); //Now we use the repository to find a model $user = $repository->find(1); //Let's save some new attributes $repository->fill($user, [ 'name' => 'Test Testerton' ]); //Finally, let's save!! $repository->save($model);
还允许更高级的查询,包括自定义查询。假设使用之前的相同仓库
//Let's query based on email AND name $user = $repository ->query() ->where('name', '=', 'Test Testerton') ->where('email', '=', 'test@test.test') ->first();
仓库的方法映射到模型的方法,在上面的示例中允许返回查询构建器。这意味着我们不会失去我们从 Eloquent 得到的任何功能。
"魔法" 方法
Laracore 的仓库支持调用魔法方法,如局部作用域查询。例如,考虑以下代码
$model = User::active()->get();
您不需要为此方法定义一个自定义仓库。
$repository = new ModelRepository(User::class); $model = $repository->active() ->get();
相反,我们可以直接在仓库上调用我们的作用域查询和其他魔法方法。仓库将委托它们到模型类。
我们的魔法方法处理也监听模型实例作为通过此仓库调用的魔法方法的第一参数。如果第一个参数是模型的实例,它将改在模型实例本身上调用该方法!请参见以下示例
//This $model = new User(); $repository->doThing($model, $stuff, $things); //Is equivalent to this $model->doThing($stuff, $things);
这是为了捕获我们想要实现而遗漏的仓库方法。如果这造成问题,请随时通过此仓库的问题联系!
关系
Laracore 还允许检索关系。
$user = $repository ->with(['tokens', 'profile']) ->find(1); //Let's also load a relation with an existing model. $repository->load($existingUser, 'comments');
ModelRepository 类具有一个 RelationRepository 设置,允许更高级的关系设置,例如 sync 和 associate。
//You can also pass in the class definition into the constructor. $profileRepository = new ModelRepository(Profile::class); $profile = $profileRepository->newModel(['stuff' => 'things']); //$repository is still set for User::class here $user = $repository->find(1); //Assuming a BelongsTo relation named profile() //on User, let's associate it! $repository ->getRelationRepository() ->associateRelation($user, 'profile', $profile); //Dont forget to save! $repository->save($user); //Assuming comment IDs... $commentIds = [1, 2, 3]; //Let's sync them to a comments relation! $repository ->getRelationRepository() ->sync($user, 'comments', $commentIds);
应表示所有关系方法,以实现多功能使用。
依赖注入
这个库最好的一点是能够依赖注入数据库访问,而不是使用静态方法。
// Rather than doing this... bad!! public function badControllerMethod() { $user = User::find(1); } //We can do this! Good! public function goodControllerMethod(ModelRepository $repository) { $repository->setModel(User::class); $user = $repository->find(1); }
这允许轻松的依赖注入,从而使得隔离测试依赖变得非常容易。
模型工厂
想要在不使用 new Model
在代码中到处创建模型?ModelFactory 正在这里帮助你!
$factory = new ModelFactory(); //We need to pass in a ModelRepository //to be able to save $factory->setRepository(new ModelRepository(User::class)); $user = $factory->make([ 'name' => 'Test Testerton' ]);
这将保存具有指定属性的模型。
您还可以使用ModelFactory
来保存BelongsTo
关系。
$user = $factory->make([ 'name' => 'Test Testerton' ], [ 'profile' => $profile ]);
继承
另一个不错的特性是您可以随意扩展这些类。您可以继续单独使用ModelRepository
,但如果您愿意,您也可以自己扩展仓库和工厂。
这里,我们将扩展ModelRepository
,这样我们就不需要每次都设置模型。我们还将默认在仓库上设置默认条件。
class UserRepository extends ModelRepository { /** * {@inheritdoc} */ public function getDefaultModel() { //We just need to pass in our default model return User::class; } }
然后,我们可以使用这个而无需设置模型!无需setModel
!
public function controllerMethod(UserRepository $repository) { $user = $repository->find(1); }
这将执行以下查询(如果使用MySQL)
SELECT * FROM `users` WHERE `name` = ? AND `id` = ?
带有两个绑定的参数'测试'和'1'。
未来计划
短期目标是保持此库与Laravel > 5的主要版本兼容。这意味着测试新版本并添加新版本中存在的新方法。
我很乐意为这个仓库添加非Eloquent支持。计划是添加原始查询以及Doctrine仓库,但这还不是时候。
长期计划不是很明确。在非Eloquent支持之后,我可能会决定接下来要实现的功能。如果您有任何想法,我非常乐意听取!