【发布时间】: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 次单独调用以分三步检索文章、类别和项目的选项。虽然在这种特殊情况下这毕竟可能是有道理的,但我仍然需要用我的项目的另一部分来处理这种特殊的反比关系问题:通知。在这种特殊情况下,通知必须与许多不同的操作/模型相关,我必须分批(分页)检索它们并按模型创建日期排序...
希望这一切都有意义。我想知道对整个逆“多态”问题采用完全不同的方法是否会有所帮助。
亲切的问候, 费德里科
【问题讨论】: