是否可以使用单独的ID数组来订购关系集合,同时仍然通过关系访问?
设置Checklist有很多ChecklistItems,我以正常的方式访问这种关系:
foreach ($list->items as $item) {
// More Code Here
}
Run Code Online (Sandbox Code Playgroud)
现在,$item作为属性$list下属性的存在的期望顺序$list->item_order,它只是$item用户所需顺序中的ID 数组,特定于$list被迭代.
是否有一种可行的方法来根据模型所具有的数组来定位$items附加的?$listitem_order$list
(我不能只在'item'表中添加'order'列,b/c顺序根据特定的'list'关系进行更改).
谢谢你的帮助!
luk*_*ter 13
你可以这样做:
$order = $list->item_order;
$list->items->sortBy(function($model) use ($order){
return array_search($model->getKey(), $order);
}
Run Code Online (Sandbox Code Playgroud)
您还可以向模型添加属性访问器,该属性访问器也是如此
public function getSortedItemsAttribute()
{
if ( ! is_null($this->item_order)) {
$order = $this->item_order;
$list = $this->items->sortBy(function($model) use ($order){
return array_search($model->getKey(), $order);
});
return $list;
}
return $this->items;
}
Run Code Online (Sandbox Code Playgroud)
用法:
foreach ($list->sortedItems as $item) {
// More Code Here
}
Run Code Online (Sandbox Code Playgroud)
如果您需要在多个地方使用此类功能,我建议您创建自己的Collection类:
class MyCollection extends Illuminate\Database\Eloquent\Collection {
public function sortByIds(array $ids){
return $this->sortBy(function($model) use ($ids){
return array_search($model->getKey(), $ids);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,newCollection()在模型中实际使用该类覆盖.在这种情况下,它将在ChecklistItems课堂上:
public function newCollection(array $models = array())
{
return new MyCollection($models);
}
Run Code Online (Sandbox Code Playgroud)
您可以尝试建立一种关系,以按您要查找的顺序返回结果。您应该仍然能够立即加载关系,并按指定的顺序获取结果。这一切都假设该item_order字段是一个逗号分隔的 id 字符串列表。
public function itemsOrdered()
{
/**
* Adds conditions to the original 'items' relationship. Due to the
* join, we must specify to only select the fields for the related
* table. Then, order by the results of the FIND_IN_SET function.
*/
return $this->items()
->select('checklist_items.*')
->join('checklists', 'checklist_items.checklist_id', '=', 'checklists.id')
->orderByRaw('FIND_IN_SET(checklist_items.id, checklists.item_order)');
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您不想对表/字段进行硬编码:
public function itemsOrdered()
{
$orderField = 'item_order';
$relation = $this->items();
$parentTable = $relation->getParent()->getTable();
$related = $relation->getRelated();
$relatedTable = $related->getTable();
return $relation
->select($relatedTable.'.*')
->join($parentTable, $relation->getForeignKey(), '=', $relation->getQualifiedParentKeyName())
->orderByRaw('FIND_IN_SET('.$related->getQualifiedKeyName().', '.$parentTable.'.'.$orderField.')');
}
Run Code Online (Sandbox Code Playgroud)
现在你可以:
$list = Checklist::with('items', 'itemsOrdered')->first();
var_export($list->item_order);
var_export($list->items->lists('id'));
var_export($list->itemsOrdered->lists('id'));
Run Code Online (Sandbox Code Playgroud)
只是警告:这是相当实验性的代码。它看起来可以处理我可用的少量测试数据,但我还没有在生产环境中做过类似的事情。此外,这仅在 HasMany 关系上进行了测试。如果您在 BelongsToMany 或类似的东西上尝试这个确切的代码,您将会遇到问题。
| 归档时间: |
|
| 查看次数: |
7704 次 |
| 最近记录: |