jamesaspence/core-model

此包已被弃用且不再维护。作者建议使用jamesaspence/laravel-core-model包代替。

一个Laravel核心模型层,包含工厂和仓库。

v1.4.0 2017-09-11 02:56 UTC

README

Eloquent模型的一个存储库、工厂和条件层,提供方便的存储库接口,同时仍然允许使用功能齐全、优雅的使用方式。允许在不牺牲功能或灵活性的情况下方便地进行测试和依赖注入。

要求

  • Laravel 5.3+

安装

composer require jamesaspence/laravel-core-model

使用

Laracore(Laravel Core Model)非常易于使用。它的工作方式与您已经熟悉的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设置,允许更高级的关系设置,例如syncassociate

//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` = ?

带有两个绑定的参数 'Test' 和 '1'。

未来计划

短期内,计划是保持这个库与 Laravel > 5 的主要版本兼容。这意味着对新版本进行测试并添加新版本中存在的新方法。

我非常愿意为此仓库添加非 Eloquent 支持。计划是添加原始查询以及 Doctrine 仓库,但这还不是时候。

长期计划稍微模糊一些。在非 Eloquent 支持之后,我可能会决定接下来要实现的功能。如果您有任何想法,我非常愿意听取!