Laravel - 检索多对多多态关系的逆(带分页)

时间:2016-02-25 16:59:00

标签: laravel eloquent

经过一些挖掘后,我仍然找不到任何可靠的方法来检索允许混合模型结果的多对多多态关系的逆。

请考虑以下事项:

我有几个可以"标记"的模型。虽然检索例如$item->tags$article->tags以及与$tag->articles$tag->items的反转是微不足道的,但我没有简单的方法来执行$tag->taggables之类的返回同一集合中的文章和项目。事情变得更加棘手,因为我需要对查询使用分页/简单分页。

我尝试了一些解决方法但是我能放在一起的最好的东西仍然看起来很糟糕且有限。基本上是:

  • 我按照" taggable";
  • 查询了一次数据库
  • 将所有内容放在一个大集合中;
  • 将该集合传递给一个phpleague / fractal变换器(我的API使用它),它根据解析的模型返回不同的json值。

这种方法的局限在于,构建分页是一场噩梦,分形"包括"选项无法开箱即用。

任何人都可以帮助我吗?我目前正在使用Laravel 5.1。

我目前的代码中没有多少魔法。伪造和简化它以缩短它:

来自api控制器:

$tag = Tag::findOrDie($tid);
$articles = $tag->cms_articles()->get();
$categories = $tag->cms_categories()->get();
$items = $tag->items()->simplePaginate($itemsperpage);

$taggables = Collection::make($articles)->merge($categories);
// Push items one by one as pagination would dirt the collection struct.
foreach ($items as $item) {
    $taggables->push($item);
}

return $this->respondWithCollection($taggables, new TaggableTransformer);

注意:使用simplePaginate()只是因为我希望所有文章和类别都显示在第一页加载,而项目数量太多需要分页。

来自Transformer类:

public function transform($taggable)
{
    switch (get_class($taggable)) {
        case 'App\Item':
            $transformer = new ItemTransformer;
            break;
        case 'App\CmsArticle':
            $transformer = new CmsArticleTransformer;
            break;
        case 'App\CmsCategory':
            $transformer = new CmsCategoryTransformer;
            break;
    }
    return $transformer->transform($taggable);
}

请考虑其他变压器只是返回与其相关的模型的数据数组。如果您使用Fractal,您很容易发现嵌套的"包含"模型不会被应用。

Tag模型没有什么特别之处:

class Tag extends Model
{   
    protected $morphClass   = 'Tag';
    protected $fillable = array('name', 'language_id');

    public function cms_articles() {
        return $this->morphedByMany('App\CmsArticle', 'taggable');
    }

    public function cms_categories() {
        return $this->morphedByMany('App\CmsCategory', 'taggable');
    }

    public function items() {
        return $this->morphedByMany('App\Item', 'taggable');
    }

    // Would love something like this to return inverse relation!! :'(
    public function taggables() {
        return $this->morphTo();
    }
}

我也在考虑选择对API进行3次单独调用,分三步检索文章,类别和项目。虽然在这种特殊情况下这可能是有意义的,但我仍然需要处理这个特殊的反向关系头痛与我的项目的另一部分:通知。在这种特殊情况下,通知必须与许多不同的动作/模型相关,我必须批量检索它们(分页)并按模型创建日期排序......

希望这一切都有意义。我想知道是否采用完全不同的方法来解决整个逆变量"多态"事情会有所帮助。

亲切的问候, 费德里科

1 个答案:

答案 0 :(得分:0)

啊,是的。我不是很久以前就走了。我有同样的噩梦处理解决多态关系的逆的倒数。

遗憾的是,Laravel生态系统中并没有引起多方关系的关注。从远处看,他们看起来像独角兽和彩虹,但很快就会发生这样的事情。

你能发布一个$thing->taggable的例子来获得更好的图片吗?认为它可以通过动态特性+访问魔术解决。