【问题标题】:How to retrieve ONLY pivot rows with Laravel Eloquent?如何使用 Laravel Eloquent 仅检索数据透视行?
【发布时间】:2020-02-14 18:18:53
【问题描述】:

我有三个模型和相关表:

  • 约会(型号:约会)
  • 疗法(模型:疗法)
  • appointment_therapies(无模型)

每次约会都可能有很多疗法(按摩、初诊、跑步等)。

通过一个搜索表单,我需要检索 - 例如 - 在所有预约中完成的所有按摩疗法,也就是说,我需要通过预约治疗表进行循环。

我试过了:

Appointment::with(['therapies' => function ($sub) use ($request) {
   $sub->where('therapy_id', $request->therapy_id);
}]) ->get();

通过这个查询,我得到了所有的约会和所有的治疗方法。

  • 约会 1
    • 疗法1
    • 疗法2
  • 约会2
    • 疗法3
    • 疗法4

因此,我无法循环治疗;我希望是这样的:

  • 疗法1
  • 疗法2
  • 疗法3
  • 疗法4

我已经编辑了 whereHas to with,这更正确。

【问题讨论】:

  • "我已经编辑了 whereHas to with,这更正确。" - 真的不是...我删除了我之前的评论,请参阅下面的 cmets,但与您的with() 逻辑,您将收到 x 个 Appointment 记录,每个 Collection 正好是 1 或 0 个 Therapy 记录,但如果是 1,它将是相同的 Therapy 记录重复对于每个Appointment.
  • 如果你使用whereHas(),正如下面的答案所示,你会得到x条Appointment记录,有0或x条Therapy记录,只要Appointment与与$request->therapy_id 匹配的Therapy。您可以将whereHas()with() 结合使用,但您希望使用whereHas('therapies', function(){ ... })->with(['therapies'])->get();(即不要在with() 子句中添加任何额外的逻辑。
  • 重点是 whereHas() 在 where 子句为真时返回所有的治疗,以及那些治疗 ID 不是请求的治疗。相反,我只需要检索具有请求的therapy_id 的疗法。
  • therapies.therapy_id 不是唯一的吗?你有 2 列,therapies.idtherapies.therapy_id?我认为您可能需要发布模型和迁移;这里有太多未知数...
  • 我需要检索有 id、appation_id 和therapy_id 的约会治疗行。

标签: php laravel eloquent pivot relationship


【解决方案1】:

pluck 方法可以返回治疗,您还应该预先加载治疗以避免运行重复查询。

$appointments = Appointment::whereHas('therapies', function ($sub) use ($request) {
   $sub->where('therapy_id', $request->therapy_id);
})->with('therapies')->get();

$therapies = $appointments->pluck('therapy');

治疗变量将是附加到第一个查询返回的约会的所有治疗的集合。

如果您需要返回的集合仍然具有预约信息,请改为基于治疗查询并急切加载相关预约

Therapy::where('id', $request->therapy_id)->with('appointments'); 

【讨论】:

  • 治疗或治疗应该可以工作, whereHas() 要求模型名称是复数,如果它是多对多但 pluck 将采用模型的名称(治疗)或返回的集合属性的名称(疗法)。至于第二部分,对于多对多关系, whereHas 闭包将采用数据透视表上的列名称(therapy_id)或非模棱两可的列名称(therapy.id),但如果您从治疗方therapy_id 没有意义
  • 我误解了第二点,修正了。但我认为第一个是正确的,我用我自己的模型测试了这段代码,这些模型具有多对多的关系。事实上,如果我 pluck('roles') 而是返回一个集合集合,这不是提问者想要的,并且只要循环遍历它们,它们就会保持在相同的位置。 ->pluck('role') 返回一个仅包含模型的集合,而不是嵌套集合。
  • 很奇怪,但我想是的,关于嵌套集合的观点是有道理的。我将不得不做更多的实验,但如果你说这有效,那就保持原样。仍然存在一个总体问题,即整个问题并不完全有意义(因为您应该使用这种逻辑只能得到一个 Therapy),但我想这不是重点。
  • OP 正在运行的查询获取包含该疗法的所有约会,它是 whereHas() 而不是 with() 所以从技术上讲,他们甚至没有加载疗法开始。约会仍然可以有其他疗法,并且 $appointment->therapies 仍然会返回与该约会相关的所有疗法。
  • 好点。我不认为我个人有一个用例,我想在没有相应的 with() 子句的情况下使用 whereHas(),但你是对的。
猜你喜欢
  • 2020-10-21
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
  • 2021-01-22
  • 2019-03-04
  • 2018-11-11
  • 2015-06-24
相关资源
最近更新 更多