
本文旨在解决 lar*el 中如何根据“has one of many”关系定义的最新关联模型对主模型进行排序的问题。通过详细分析直接联接的局限性,文章将重点介绍并演示使用子查询联接(`joinsub`)作为一种高效且优雅的解决方案,以确保准确地按最新关联数据对父模型进行排序,避免重复记录,并提供清晰的代码示例和实现步骤。
在 Lar*el 应用开发中,我们经常会遇到需要从多个相关联的子模型中选择“最新”或“最旧”的那一个,并将其作为父模型的一个属性来访问。Lar*el 提供的“Has One Of Many”关系正是为此而生。例如,一个 Customer(客户)模型可能拥有多个 Contact(联系记录),我们希望能够轻松获取每个客户的最新联系记录。
模型定义示例:
// app/Models/Customer.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
use HasFactory;
public function contacts()
{
return $this->hasMany(Contact::class);
}
public function latestContact()
{
// 定义“Has One Of Many”关系,获取每个客户最新联系时间(contacted_at)的联系记录
return $this->hasOne(Contact::class)->ofMany('contacted_at', 'max')->withDefault();
}
}// app/Models/Contact.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Contact extends Model
{
use HasFactory, SoftDeletes;
protected $casts = [
'contacted_at' => 'datetime',
];
public function customer()
{
return $this->belongsTo(Customer::class);
}
}迁移文件(contacts 表):
// database/migrations/..._create_contacts_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateContactsTable extends Migration
{
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->softDeletes();
$table->foreignId('customer_id')->constrained()->onDelete('cascade');
$table->string('type');
$table->dateTime('contacted_at');
});
}
public function down()
{
Schema::dropIfExists('contacts');
}
}现在,挑战在于如何根据这个 latestContact 关系中的 contacted_at 字段对所有 Customer 进行排序。直接使用 join 方法并尝试 orderBy('contacts.contacted_at') 通常会导致每个客户出现多条记录,因为 join 会将所有匹配的联系记录都连接到客户上,这不是我们期望的结果。我们需要的是每个客户只对应一条最新的联系记录,并基于此进行排序。
Lar*el 的查询构建器提供了 joinSub 方法,它允许我们将一个查询结果作为子查询,并将其联接到主查询中。这是解决上述问题的最简洁和高效的方法。
核心思路是:
具体实现步骤与代码:
Freepik Mystic
Freepik Mystic 是一款革命性的AI图像生成器,可以直接生*高清图像
174
查看详情
use Illuminate\Support\Facades\DB;
use App\Models\Customer;
use App\Models\Contact;
// 1. 构建子查询:找出每个客户的最新联系时间
$latestContactsSubquery = Contact::select('customer_id', DB::raw('MAX(contacted_at) as latest_contact'))
->groupBy('customer_id');
// 2. 将子查询联接到 Customer 模型上,并根据最新联系时间排序
$customers = Customer::select('customers.*', 'latest_contacts.latest_contact')
->joinSub($latestContactsSubquery, 'latest_contacts', function ($join) {
$join->on('customers.id', '=', 'latest_contacts.customer_id');
})
->orderBy('latest_contacts.latest_contact', 'desc') // 降序排列,最新联系的客户在前
->get();
// $customers 现在包含了按最新联系时间排序的客户列表,每个客户都带有一个 latest_contact 字段
foreach ($customers as $customer) {
echo "客户ID: {$customer->id}, 最新联系时间: {$customer->latest_contact}\n";
// 也可以通过预加载来访问 latestContact 关系
// $customer->load('latestContact');
// echo "最新联系人类型: " . $customer->latestContact->type . "\n";
}代码解析:
$latestContactsSubquery = Contact::select('customer_id', DB::raw('MAX(contacted_at) as latest_contact'))->groupBy('customer_id');
*`Customer::select('customers.', 'latest_contacts.latest_contact')`**
->joinSub($latestContactsSubquery, 'latest_contacts', function ($join) { $join->on('customers.id', '=', 'latest_contacts.customer_id'); })
->orderBy('latest_contacts.latest_contact', 'desc')
通过利用 Lar*el 强大的查询构建器中的 joinSub 方法,我们可以优雅且高效地解决根据“Has One Of Many”关系定义的最新关联模型对父模型进行排序的问题。这种模式不仅保证了数据结果的准确性,也提升了代码的可读性和维护性,是处理此类复杂排序场景的推荐方法。在实际应用中,结合数据库索引优化,可以进一步提升查询性能。
以上就是Lar*el 中按“Has One Of Many”关联模型排序的最佳实践的详细内容,更多请关注php中文网其它相关文章!
# laravel
# cad
# php
# 乐至抖音推广招聘网站
# 湖北创意seo推荐
# 东莞日产汽车网站建设
# 页面 seo tag
# 过年如何营销推广产品
# 网络推广seo文章
# 通州整合网络营销推广
# 排名推广优化技术网站
# 转转 关键词 分类排名
# 网站优化类公司排名推广
# 来访问
# 这种方法
# 降序
# 加密文件
# 这是
# 的是
# 并将其
# 怎么看
# 多个
# 查询结果
# 排列
# 聚合函数
# 应用开发
# ai
# app
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
WooCommerce 新客户订单自动添加管理员备注教程
电脑视频号|直播|如何分享屏幕
《咸鱼之王》新版孙坚技能解析
OPPO手机参数配置如何开启护眼模式_OPPO手机参数配置护眼模式开启指南
《七读免费小说》开通会员方法
Excel如何快速找到并断开外部数据源链接_Excel外部数据源断开方法
银信通自动开通原因揭秘
126邮箱网页在线登录2025_126邮箱网页版入口官方地址
《跳跳舞蹈》循环播放方法
Three.js中动态更换3D模型纹理的教程
知乎APP怎么查看自己被邀请的问题_知乎APP邀请回答记录查看与参与方法
PHP 4 函数中引用参数的默认值限制与解决方案
小米手机屏幕失灵乱跳怎么办 屏幕触控问题自检与临时解决方法【应急】
优化 React onClick 事件处理:函数引用与箭头函数的对比
Go语言反射机制下访问嵌入结构体中的被遮蔽方法
Git命令与VS Code UI操作的对应关系解析
HTML中多图片上传与预览:解决ID冲突的专业指南
天堂漫画网页版在线阅读 天堂漫画手机版入口
composer 提示 "requires ext-soap" 缺少 SOAP 扩展怎么办?
在PHP环境中正确加载HTML资源:CSS样式与图片路径指南
《我的恋爱逃生攻略》中文名字输入方法
如何编写一个符合 composer 规范的 post-install-cmd 脚本?
漫蛙官网(首页入口)_漫蛙漫画稳定访问教程分享
如何快速去除厨房重油污? 2025年最好用的厨房清洁剂推荐
青橙手机语音助手怎么唤醒_青橙手机语音助手设置与唤醒方法
《kimi智能助手》制作ppt教程
CSS如何使用outline-offset与颜色组合突出元素边框
excel怎么制作考勤表 excel考勤模板与函数公式讲解
Excel如何快速合并单元格内容_Excel文本合并与函数操作技巧
J*a中为什么强调组合优于继承_组合模式带来的灵活性与可维护性解析
纯CSS实现滚动时动态时间轴线条颜色填充效果
京东快递物流信息不更新怎么办_物流停滞原因与处理方法
J*aScript二进制处理_ArrayBuffer与Blob
抖音手机分身两个账号怎么切换?分身两个系统是一样的吗?
火柴人战争网页版在线玩
京东快递包裹信息查询入口 京东快递官方查询平台入口
解决CSS布局中意外顶部空白问题的教程
铁路12306官网入口 铁路12306中国铁路官网登录首页
mysql如何配置从库只读_mysql从库只读设置方法
TikTok笔记文字无法编辑如何解决 TikTok笔记文字编辑优化方法
传统曲艺莲花落的表演形式是
Vue 3中独立响应式实例的创建与应用
谷歌浏览器官方镜像获取方法_谷歌浏览器网页版入口极速直达
iPhone14开启Apple TV遥控设置
汽水音乐车机版官网5.0 汽水音乐车机版5.0版本下载入口
聚水潭ERP后台管理系统登录 聚水潭ERP官方登录通道
米侠浏览器插件无法启用怎么办 米侠浏览器扩展兼容性修复
圆通快递包裹轨迹查询 圆通速递快件实时位置跟踪
4399造梦西游3无敌版_4399游戏入口
苹果手机手电筒无法开启
2025-12-01
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。