【问题标题】:Checking, if Model C is related with any Model B related with Model A检查模型 C 是否与模型 A 相关的任何模型 B 相关
【发布时间】:2013-09-09 14:58:17
【问题描述】:

我知道这看起来很复杂,但我会解释一下。

  • 我有 3 个模型,我们称它们为 A、B 和 C。
  • 它们都可以通过多对多关系与其他人关联。

我想检查模型 C 是否与任何模型 B 相关,而模型 B 与我的模型相关。

我想通过 Model C 的“名称”列而不是 ID 来检查它。

【问题讨论】:

  • 只做一个(内部)连接,看看是否返回任何记录?
  • @NDM:我不太明白,该怎么做。此外,如果在数据透视表上完成内连接,则按 ID 搜索,因此我必须执行另一个查询来获取我的 Model C 的 ID。我想得到具体的答案。
  • SELECT * FROM model_a JOIN model_a.name = model_b.name_of_a; 如果返回任何行,则有 A 与 B 有链接
  • @NDM:您还没有阅读整个问题。它是 Laravel 4,所以我想用 Eloquent 风格(如标记)来做这件事,而原始 SELECT deos不适合那里,因为 Eloquent 有 join 方法。它是多对多的,所以它是通过数据透视表完成的,因此没有 model_b.name_of_a
  • 检查是否相关是什么意思?你的意思是如果模型 A 有一些模型 B 类型的条目(例如,检查 Post 是否有 Comments ?)

标签: php mysql laravel laravel-4 eloquent


【解决方案1】:

编辑:

在 irc 上进行了一些挖掘和询问后,结果发现我以前的方法根本不是解决这个问题的正确方法:)

感谢@Oddman 和@Kindari 对讨论的大力投入 - 如建议的那样,要测试两个“多对多模型”A 和 B 是否相关,您可以使用列表方法 (Illuminate\Support\Collection)

in_array($b->id, $a->related()->lists('b_id'))

如果接下来您想通过“名称”检查 C 是否与 B 相关,您能否提供有关此列在关系中如何使用的详细信息 - 您是否将其显示在数据透视表中?如果是这样,也许您可​​以尝试以下方法-但这只是我在这里的疯狂猜测...

in_array($c->name, $b->related()->lists('c_name'))

除了上述之外,您始终可以使用适当的连接执行原始 sql 查询,这是使其正常工作的可靠方法。你可以从@NDM 建议的地方开始。

查看文档当然也是一件好事:
http://four.laravel.com/docs/eloquent#many-to-many
http://four.laravel.com/docs/eloquent#working-with-pivot-tables

【讨论】:

  • 不正确。它可用于获取,如果我的模型 A 有模型 C。不,我想检查与我的模型 A 相关的模型 B 是否与特定的模型 C 相关。
  • 我根据您的评论编辑了我的答案。如果这仍然不是您需要的概念 - 将模型的代码粘贴到您的问题中或此处 - paste.laravel.com - 并在您的 OP 中提交链接 - 问候
  • 那么,我是否需要遍历数组并检查是否是这样?
  • 以前的答案根本不正确,请检查当前的编辑:)
  • 问题是,我不想关心 B 的名字。看起来我必须知道特定的 B。问题是,我想检查 C 是否与 A 的任何 B 相关。
【解决方案2】:

只使用几个内连接怎么样? Eloquent 的好处在于,您始终可以使用 Laravel's DB query builder 作为 Eloquent 模型的一部分来处理更复杂的情况,因为 Eloquent 是基于 Query builder 构建的。

    $a = A::select('a.id, a.name, b.id, b.name, c.id, b.name')
                    ->join('a_b_pivot', 'a.id', '=', 'b.a_id')
                    ->join('b_c_pivot', 'b.id', '=', 'c.b_id')
                    ->join('b', 'a_b_pivot.b_id', '=', 'b.id')
                    ->join('c', 'b_c_pivot.c_id', '=', 'c.id')
                    ->where('c.name', '=', $name);

可能不是最有效的方法,但应该比遍历模型并将所有内容加载为模型等更有效。

请确保您提及所有带有表名的字段,否则它不起作用。根据您希望从查询中返回的模型,您还可以从 C:: 或 B:: 开始查询并据此调整它。

其他有用的东西可能是使用预先加载作为查询的一部分,或者在获得结果后使用 ->load('b,c)。

别忘了你可以 create query scope 离开这个,所以它很容易在代码的任何地方重用:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 2017-03-23
    • 1970-01-01
    • 2014-07-17
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    相关资源
    最近更新 更多