Laravel 5.2实现Fees表关联两个同字段班级表的学生显示
Laravel 5.2 根据Class_id匹配对应班级学生的实现方案
方案一:动态模型关联实现
由于Class A和Class B表结构完全一致,可先创建通用Student模型,再在Fees模型中定义动态关联方法,根据当前记录的Class_id关联对应数据表:
namespace App; use Illuminate\Database\Eloquent\Model; class Fees extends Model { protected $table = 'fees'; // 关联对应班级的学生 public function student() { $targetTable = $this->class_id === 'A' ? 'class_a' : 'class_b'; return $this->belongsTo(Student::class, 'student_id', 'id')->setTable($targetTable); } } // 通用Student模型(无需指定固定表名) class Student extends Model { }
使用时直接调用关联即可获取对应学生:
$fees = Fees::with('student')->get(); foreach ($fees as $fee) { // 输出对应班级的学生姓名 echo $fee->student->student_name; }
方案二:查询构建器直接关联查询
若不需要模型关联,可直接用DB门面编写查询语句,通过条件关联合并字段:
$fees = \DB::table('fees') ->leftJoin('class_a', function($join) { $join->on('fees.student_id', '=', 'class_a.id') ->where('fees.class_id', '=', 'A'); }) ->leftJoin('class_b', function($join) { $join->on('fees.student_id', '=', 'class_b.id') ->where('fees.class_id', '=', 'B'); }) ->select( 'fees.*', \DB::raw('COALESCE(class_a.student_name, class_b.student_name) as student_name'), \DB::raw('COALESCE(class_a.address, class_b.address) as address') ) ->get();
该查询会自动根据fees表的class_id,从对应班级表中取出学生信息,避免学号重复导致的混淆。
方案三:模型访问器(适合简单场景)
在Fees模型中添加访问器,动态获取对应班级的学生数据:
namespace App; use Illuminate\Database\Eloquent\Model; class Fees extends Model { protected $table = 'fees'; public function getStudentInfoAttribute() { $modelClass = $this->class_id === 'A' ? ClassA::class : ClassB::class; return $modelClass::find($this->student_id); } } // 分别创建ClassA和ClassB模型 class ClassA extends Model { protected $table = 'class_a'; } class ClassB extends Model { protected $table = 'class_b'; }
使用时通过$fee->student_info即可获取学生对象,但此方式会产生N+1查询问题,数据量大时建议优先使用方案一或二。
注意:数据库表名建议统一使用小写蛇形命名(如
class_a、class_b),确保与模型配置一致。
内容的提问来源于stack exchange,提问作者Karthik SWOT
相关产品推荐
相关产品推荐

