将存储库方法应用于关系模型

Applying repository method to relationship models

我有 2 个关于分类法及其子术语的回购协议。我已经设置了接口等等,并通过一些代码来清理它并从我的控制器中删除 eloquent 从而也使它们变瘦。

我正在努力思考如何在不出错的情况下将方法应用于子关系。请放轻松,我正在学习这个,但感觉我错过了一些非常明显的东西,并且绕着圈子转,失去了我到目前为止尝试过的一切。

MyController.php

$taxonomy = $taxonomies->findBySlug($this->taxonomy_name);

if ( isset($taxonomy->id) ) {

    // The below line worked and what im trying to replace below to remove firstOrCreate from my controller

    //$taxonomy->term()->firstOrCreate(array('name' => $request->name, 'slug' => str_slug($request->name)));

    $taxonomy->term()->createTermFromSlug($request->name);
}

TaxonomyInterface.php

interface TaxonomyInterface{

    public function createTermFromSlug($term_name);
}

DBTaxonomyRepository

class DBTaxonomyRepository 
extends AbstractDBRepository 
implements TaxonomyInterface
{

    protected $table = 'taxonomy';

    public $timestamps = false;

    public function term()
    {
        return $this->hasMany('App\Repositories\DBTaxonomyTermRepository', 'taxonomy_id', 'id');
    }

    /**
     * Create term based on unique slug.
     *
     * @param $term_name
     * @internal param $name
     */
    public function createTermFromSlug($term_name)
    {
        $term = $this->firstOrCreate(array(
            'slug' => str_slug($term_name)
        ));

        $term->name = $term_name;

        $term->save();
    }
}

我已经尝试了很多东西,现在我显然遗漏了一些基本的东西,我无法通过反复试验来学习它。这是我离开它的当前状态。

简而言之,我想将存储库方法应用于术语实体的分类实体,从而使 eloquent 与控制器分离。

我希望在之后对其进行抽象,以便我可以在处理不同分类法的各种不同控制器中重用它。

通过将所有内容转储到存储库中的方式,我认为您只是在用一个问题(胖控制器)换取另一个问题(上帝 class 存储库试图做太多事情)。

我会稍微改变一下结构,这样您的存储库就不再是您的模型,而是将模型注入到您的存储库中。这是一个示例存储库。

use App\Terms;
use App\Taxonomy;

class TaxonomyRepository
{
    protected $term;
    protected $taxonomy;

    // Here we are injecting your Term and Taxonomy models
    public function __construct(Term $term, Taxonomy $taxonomy)
    {
        $this->term = $term;
        $this->taxonomy = $taxonomy;
    }

    /**
     * Create term based on unique slug.
     *
     * @param $term_name
     * @internal param $name
     */
    public function createTermFromSlug($term_name)
    {
        $term = $this->term->firstOrCreate([
            'slug' => str_slug($term_name)
        ]);

        $term->name = $term_name;

        $term->save();
    }

    public function findTaxonomyBySlug($slug)
    {
        return $this->taxonomy->where('slug', $slug)->first();
    }
}

我不确定您是否还需要扩展和工具,所以我将它们排除在外。

然后您只需将您的存储库注入您的控制器...

class MyController
{
    protected $taxRepo;

    // Here we are injecting your Repository into the controller
    public function __construct(TaxonomyRepository $taxRepo)
    {
        $this->taxRepo = $taxRepo;
    }

    public function store(Reques $request)
    {
        $taxonomy = $this->taxRepo->findTaxonomyBySlug($this->taxonomy_name);

        if ( isset($taxonomy->id) ) {
            $this->taxRepo->createTermFromSlug($request->name);
        }
    }
}

这个想法很简单。每个 class 应该只做一件事(并希望做好)。其中一个 class 依赖于另一个(例如存储库需要术语和税收模型),让 Laravel 为您注入它们。