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

时间:2016-07-07 12:20:41

标签: laravel eloquent repository-pattern

我有2个回归分类及其子条款。我已经设置了界面等等,并且正在通过一些代码来清理它并从我的控制器中删除雄辩,从而使它们变得很瘦。

我正在努力探索如何将方法应用于子关系而不会出错。请轻松地学习这个,但是我觉得我错过了一些明显的东西,并且在圈子里走动,失去了我迄今为止所做的一切。

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();
    }
}

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

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

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

1 个答案:

答案 0 :(得分:1)

通过将所有内容转储到存储库中的方式,我认为您只是针对另一个问题(胖类控制器)处理另一个问题(上帝类存储库试图做太多)。

我会以不同的方式构建它,以便您的存储库不是您的模型,而是将模型注入到您的存储库中。这是一个示例存储库。

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);
        }
    }
}

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

相关问题