【问题标题】:Laravel - Retrieve the inverse of a many-to-many polymorphic relation (with pagination)Laravel - 检索多对多多态关系的逆(分页)
【发布时间】:2016-02-25 16:58:59
【问题描述】:

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

请考虑以下几点:

我有几个可以“标记”的模型。虽然检索例如$item->tags$article->tags$tag->articles$tag->items 的反函数很简单,但我没有简单的方法来执行$tag->taggables 之类的操作来返回同一集合中的文章和项目。事情变得更加坎坷,因为我需要对查询使用分页/简单分页。

我已经尝试了一些解决方法,但我能总结出的最好的方法仍然看起来很糟糕而且很有限。基本上:

  • 我为每个“可标记”查询了一次数据库;
  • 将所有内容放在一个大集合中;
  • 将集合传递给 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,您会很容易发现嵌套的“包含”模型不会被应用。

标签模型没什么特别的:

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 次单独调用以分三步检索文章、类别和项目的选项。虽然在这种特殊情况下这毕竟可能是有道理的,但我仍然需要用我的项目的另一部分来处理这种特殊的反比关系问题:通知。在这种特殊情况下,通知必须与许多不同的操作/模型相关,我必须分批(分页)检索它们并按模型创建日期排序...

希望这一切都有意义。我想知道对整个逆“多态”问题采用完全不同的方法是否会有所帮助。

亲切的问候, 费德里科

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    啊,是的。不久前我走在你的路上。我有同样的噩梦来处理解决多态关系的逆关系。

    不幸的是,多态关系在 Laravel 生态系统中并没有得到太多关注。从远处看,它们看起来像独角兽和彩虹,但很快你就会与这样的东西作斗争。

    您能否发布$thing->taggable 的示例以获得更好的图片?认为它可以通过动态特征 + 访问器魔法来解决。

    【讨论】:

    • 试图添加一些注意事项和一些示例代码......我想知道这整件事是否有意义,或者(除了实现困难)还有其他原因导致它不在 ORM 中(例如。最佳实践)。
    • 迪伦,你是怎么解决这个问题的?我应该以完全不同的方式处理这个问题吗?
    猜你喜欢
    • 1970-01-01
    • 2015-04-23
    • 2017-05-25
    • 2019-08-17
    • 2017-01-17
    • 1970-01-01
    • 2017-02-28
    • 2016-07-19
    • 2023-03-12
    相关资源
    最近更新 更多