php - 获取在所选行之前创建的行
问题描述
我想知道获得在选定行之前创建的所有行的计数的最佳方法。现在我已经定义了一个看起来像这样的访问器:
// In the model
public function getPositionAttribute() {
return self::where([
// Some other condition
['created_at', '<', $this->created_at->toDateTimeString()]
])->count();
}
// In the code
$model->position
它工作正常,但我担心两件事:
- 调用
self
模型是一种不好的做法吗?在我看来不知何故。 - 当在 a 中调用时,
foreach
这显然会为每个远非最佳的元素生成一个查询。有什么方法可以重构它,以便可以在单个查询中预先加载它?
奖励:我完全放弃了使用某种索引来保留列的想法,因为最初听起来无法维护,例如。当一条记录被删除时,所有其他记录都应该以某种方式转移位置。我应该重新考虑吗?有没有更好的办法?
解决方案
很确定在这里使用 self 是“最佳实践”,因为这就是该关键字的设计方式。
关于重构,我个人无法考虑按原样优化查询,但您可以创建一个函数来预加载所有位置,然后正常使用它。假设您的模型具有唯一键“id”并且您正在传递模型集合,那么您可以尝试以下操作:
public static function populateOrderPositions($modelCollection){
// Optimize this query to include your "other condition"
$idCollection = Model::orderBy('created_at') // this will make it in the order of creation
->pluck('id'); // this will only retrieve the id field
// This array will contain an array with the model object ids as key and a numeric position (starts at 0)
$positionArr = $idCollection->flip()->all();
// Then just load all the position into the object and return it.
return $modelCollection->map(function($modelObj) use ($positionArr){
return $modelObj->position = $positionArr[$modelObj->id] + 1; // +1 because array key starts at 0
};
}
您还需要调整属性代码以使用加载的属性,而不是像这样忽略加载的属性:
public function getPositionAttribute() {
return $this->attributes['position'] ?? self::where([
// Some other condition
['created_at', '<', $this->created_at->toDateTimeString()]
])->count();
}
通过这些更改,您可以预先填充该位置,然后使用它,而无需查询数据库。
这些代码未经测试,因为我不知道您的模型和查询将如何构建,并且只是一个示例。您还需要将性能与原始代码进行比较。
推荐阅读
- wordpress - wordpress 网络服务器 WAN/LAN 连接错误
- javascript - jQuery 提交需要两次点击才能工作
- pine-script - 在绘图上使用样式变量
- angular - 在 Highcharts 上删除或切换事件
- java - 如何在 Java 中创建更多对象?
- machine-learning - 如何增加文档标题的重要性以便为文档聚类找到好的特征?
- java - 尝试运行动态 Web 项目时出现错误 404
- html - 如何将子元素定位在固定位置父元素的底部
- twig - 带有 ${ text } 的 Twig if 语句
- javascript - 如何在纯 JavaScript 的外部 HTML/SVG 文件中执行 javascript?