我正在构建一个具有projects
且项目有plot_types
的应用程序。
我希望能够检查当前项目下是否存在plot_type。
我有以下代码:
$testResult = $project->with(['plotTypes' => function($query) use ($row) {
$query->where('name', $row->plot_name);
}])->first()
这会生成以下MySQL:
select exists(select * from `projects` where exists (select * from `projects_plot_types` where `projects_plot_types`.`project_id` = `projects`.`id` and `name` = ?)) as `exists`
此SQL返回与$project
对象无关的行。例如,当我dd($project)
时,我得到:
#attributes: array:11 [▼
"id" => "4"
"name" => "xxx"
"number" => "1234"
"builder" => "1"
"overall_budget" => "3456.00"
"start_date" => "2016-03-31"
"end_date" => "2016-04-30"
"created_date" => "2016-03-16 15:22:05"
"updated_date" => "2016-03-16 15:22:07"
]
然而,当我dd($testResult);
时,它会给出;
#relations: array:1 [▼
"plotTypes" => Collection {#767 ▼
#items: array:1 [▼
0 => ProjectsPlotTypes {#770 ▼
#table: "projects_plot_types"
#fillable: array:2 [▶]
+timestamps: false
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
#attributes: array:4 [▼
"id" => "1"
"project_id" => "1"
"name" => "TYPE 1 - VENTILATION"
"budget" => "324.67"
]
注意,上面的project_id显示1
。这与当前项目无关,因为当前项目ID为4
。
为什么会这样?
答案 0 :(得分:1)
这是ActiveRecord模型中可能令人困惑的部分之一。您的所有模型实例都包含用于检索模型实例的相同方法,因此很容易认为某些内容在某些方面确实不起作用。
调用$project->with()
,这与调用Project::with()
完全相同。即使您在项目实例上调用with()
,也不会将加载的对象限制为仅与您的实例相关的对象。
当您致电$project->with()
时,它首先要做的是为所有项目创建一个新查询,然后添加急切加载。然后调用first()
,它只获取第一个项目记录,以及所有其急切加载的对象。
要获取特定项目的绘图类型,您有几个选项。
只需查询关系。 $project->plotTypes()
为您提供与项目关联的所有绘图类型的基本查询。您可以添加约束并从那里获取记录。
$plotTypes = $project->plotTypes()->where('name', $row->plot_name)->get();
dd($plotTypes);
使用约束加载相关的绘图类型:
// assume your project doesn't have any plottypes loaded yet
$project = Project::find(1);
// load the plottypes relation with constraints
$project->load(['plotTypes' => function($query) use ($row) {
$query->where('name', $row->plot_name);
}]);
dd($project->plotTypes);
过滤已加载的Collection
相关绘图类型。 $project->plotTypes
包含与您的项目相关的所有绘图类型,但您可以使用where()
上的Collection
方法(与查询中的where()
不同)来过滤记录在Collection
。
// assume your project already has all plotTypes loaded
$project = Project::with('plotTypes')->find(1);
// you just want to get a subset of those pre-loaded plottypes
$plotTypes = $project->plotTypes->where('name', $row->plot_name);
dd($plotTypes);
答案 1 :(得分:0)
使用whereHas方法进行过滤,而不是使用with
$testResult = $project->whereHas('plotTypes' => function($query) use ($row) {
$query->where('name', $row->plot_name);
})->with('plotTypes')->first();
此外,您想要获取所有相关记录还是仅第一个记录?
如果全部,则将第一个()更改为获取()
希望这有帮助