Eloquent关联:双父模型与子模型指定结构JSON查询需求
解决方案
要生成你需要的JSON结构,关键是在模型间建立正确的关联关系,然后通过关联查询获取关联表的字段,最后映射成目标格式。下面是分步实现:
1. 完善模型关联
首先,我们需要给三个模型建立关联——试题表(questions)应该属于一个题库和一个题型,而题库和题型可以拥有多个试题。
题库模型(Questionbank)
调整模型,添加和试题的关联,并确保需要的字段可见:
class Questionbank extends Model { protected $fillable = []; protected $table = "QuestionBank"; protected $dates = []; protected $primaryKey = "QuestionBankID"; // 确保关联时能获取到QuestionBank字段 protected $visible = ["QuestionBank", "QuestionBankID"]; // 一个题库对应多个试题,关联字段是QuestionBankID public function questions() { return $this->hasMany(Questions::class, 'QuestionBankID'); } }
题型模型(Questiontype)
补全模型的必要配置和关联(根据你的实际表结构调整字段名):
class Questiontype extends Model { // 替换成你实际的表名 protected $table = "questiontype"; // 替换成你实际的主键字段名 protected $primaryKey = "QuestiontypeID"; // 确保能获取到题型名称字段(这里假设字段名是questiontype) protected $visible = ["questiontype"]; // 一个题型对应多个试题,关联字段是QuestiontypeID public function questions() { return $this->hasMany(Questions::class, 'QuestiontypeID'); } }
试题模型(Questions)
创建/完善试题模型,定义和题库、题型的从属关联:
class Questions extends Model { protected $table = "questions"; // 允许批量赋值的字段,根据你的实际字段调整 protected $fillable = ['questiontitle', 'QuestionBankID', 'QuestiontypeID']; protected $visible = ['questiontitle']; // 试题属于一个题库 public function questionbank() { return $this->belongsTo(Questionbank::class, 'QuestionBankID'); } // 试题属于一个题型 public function questiontype() { return $this->belongsTo(Questiontype::class, 'QuestiontypeID'); } }
2. 查询并生成目标JSON
在控制器中,通过关联查询获取所有试题及其关联的题库和题型,然后映射成你需要的结构:
// 预加载关联的题库和题型,避免N+1查询问题 $questions = Questions::with(['questionbank', 'questiontype'])->get(); // 转换为目标JSON结构 $formattedQuestions = $questions->map(function($question) { return [ 'questiontitle' => $question->questiontitle, 'questionbank' => $question->questionbank->QuestionBank, // 对应题库表的QuestionBank字段 'questiontype' => $question->questiontype->questiontype // 对应题型表的questiontype字段 ]; }); // 返回JSON响应 return response()->json($formattedQuestions);
注意事项
- 确保数据库表中的外键字段(比如
questions表的QuestionBankID和QuestiontypeID)正确关联到对应表的主键。 - 如果你的题型表或题库表的字段名和示例不同,需要调整代码中对应的字段引用(比如把
questiontype换成你实际的题型名称字段)。 - 使用
with()方法预加载关联,可以避免Laravel的N+1查询问题,提升性能。
内容的提问来源于stack exchange,提问作者Yuvaraj Rajendran
相关产品推荐
相关产品推荐

