我希望使用Laravel Eloquent with()
method在3个表之间建立关系。
这是我的代码(关系在模型中设置):
$request_form = RequestForm::find(7)->with(['RequestFormsCheck' => function ($q) {
$q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions');
}])->get();
dd($request_form);
但此代码会返回所有request forms
,但仅返回id = 7
这是输出:
Collection {#895 ▼
#items: array:4 [▼
0 => RequestForm {#796 ▶}
1 => RequestForm {#797 ▶}
2 => RequestForm {#798 ▶}
3 => RequestForm {#799 ▶}
]
}
当我将->get()
替换为->first()
时,它只返回request form
,但其id
为1 :(
但是这段代码效果很好:
$request_form = RequestForm::where('id', 7)->with(['RequestFormsCheck' => function ($q) {
$q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions');
}])->first();
dd($request_form->toArray());
这是它的输出(这是我期望得到的):
array:12 [▼
"id" => 7
"name" => "Jack"
"email" => "jack@gmail.com"
"telephone" => null
"description" => "..."
"site" => "http://branch.local/"
"item_id" => 10
"lang" => "en"
"read" => 1
"created_at" => "2018-05-15 11:09:47"
"updated_at" => "2018-05-20 05:24:41"
"request_forms_check" => array:1 [▼
0 => array:8 [▼
"id" => 1
"request_form_id" => 7
"type" => 2
"request_forms_check_options_id" => null
"description" => "custom note"
"created_at" => "2018-05-15 11:48:36"
"updated_at" => "2018-05-15 11:48:36"
"request_forms_check_options" => null
]
]
]
这些是我的迁移:
Schema::create('request_forms', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 100)->nullable();
$table->string('email', 100)->nullable();
$table->string('telephone', 20)->nullable();
$table->text('description')->nullable();
$table->string('site', 100);
$table->integer('item_id');
$table->string('lang');
$table->timestamps();
});
和
Schema::create('request_forms_check_options', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 500);
$table->timestamps();
});
和这个
Schema::create('request_forms_checks', function (Blueprint $table) {
$table->increments('id');
$table->integer('request_form_id')->unsigned();
$table->foreign('request_form_id')->references('id')->on('request_forms')->onDelete('cascade');
$table->tinyInteger('type')->comment("1: option, 2:description");
$table->integer('request_forms_check_options_id')->unsigned()->nullable();
$table->foreign('request_forms_check_options_id')->references('id')->on('request_forms_check_options')->onDelete('cascade');
$table->text('description')->nullable();
$table->timestamps();
});
答案 0 :(得分:2)
首先,我会将您推荐给this answer,但为了记录起见,我会再次解释:
当你使用find()
方法时,已经返回了Model的一个实例(这不是查询构建器),这就是为什么在find的结果上使用with()
将对数据库进行新的查询然后调用get()
on返回整个记录,而调用first()
将返回第一条记录(按id)。
我建议如何解决这个以防你还想坚持find()
让find()
在查询之后(eager loaded)。例如:
$request_form = RequestForm::with(['RequestFormsCheck' => function ($q) {
$q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions');
}])->find(7);
查找后使用load()
(延迟加载) - 您有结果然后加载相关模型。例如:
$request_form = RequestForm::find(7)->load(['RequestFormsCheck' => function ($q) {
$q->orderBy("created_at", "DESC")->with('RequestFormsCheckOptions');
}]);
在调用最终结果之前,坚持在整个查询中调用with()
(有效的)。我认为这是最好的方法,因为你只需要一个 RequestForm,然后很多与
上阅读更多内容我对
with()
工作的一般理解是在查询构建器上,因此您必须在with()
相关之前将查询聚在一起(这可能需要更新)。