【问题标题】:Laravel Eloquent hasMany\hasOne limit parents to children with recordsLaravel Eloquent hasMany\hasOne 将父母限制为有记录的孩子
【发布时间】:2015-12-23 22:43:30
【问题描述】:

使用 Laravel Eloquent 和 hasOne()\hasMany() 关系,是否可以限制“父”表仅在存在“子\外部”关系时才检索结果?

FOOS

+----+------------+
| id |     etc    |
+----+------------+
|  1 |     one    |
|  2 |     two    |
|  3 |     three  |
|  4 |     four   |
+----+------------+

酒吧

+----+-----+--------+
| id | val | foo_id |
+----+-----+--------+
| 11 | 101 |      1 |
| 12 | 102 |      2 |
| 13 | 203 |      3 |
| 14 | 204 |      4 |
+----+-----+--------+

在 Foo 类(模型)中

public function highBars(){
    return $this->hasOne('App\Bar')->where('val','>','200');
}

在控制器中

Foo::with('highBars')->get();

返回所有 FOOS,即使某些 high_bars 关系为空。 是否可以只包含关系值不为空的 FOOS 结果? (foos.id = 3,4)

这是检索到...

  0 => array:3 [▼
    "id" => 1
    "etc" => "one"
    "high_bars" => null
  ]
  1 => array:3 [▼
    "id" => 2
    "etc" => "two"
    "high_bars" => null
  ]
  2 => array:3 [▼
    "id" => 3
    "etc" => "three"
    "high_bars" => array:2 [▼
      "id" => 13
      "val" =>203
      "foo_id" =>3
    ]
  ]
  3 => array:3 [▼
    "id" => 4
    "etc" => "four"
    "high_bars" => array:2 [▼
      "id" => 14
      "val" =>204
      "foo_id" =>4
    ]
  ]

但这就是我想要的..

0 => array:3 [▼
    "id" => 3
    "etc" => "three"
    "high_bars" => array:2 [▼
      "id" => 13
      "val" =>203
      "foo_id" =>3
    ]
  ]
  1 => array:3 [▼
    "id" => 4
    "etc" => "four"
    "high_bars" => array:2 [▼
      "id" => 14
      "val" =>204
      "foo_id" =>4
    ]
  ]

【问题讨论】:

  • 其他答案回答了问题(您正在寻找has(),但我想指出的是,由于Foo 包含bar_id 外键,所以关系是@987654331 @ 属于Bar,而Bar 有一个(或多个)Foo
  • 你说得对@patricus,当我写这篇文章时我很困,今天早上应用它时意识到,有些地方不正确..

标签: php laravel


【解决方案1】:

引用documentation

访问模型的记录时,您可能希望限制您的 结果基于关系的存在。例如,想象 您想检索至少有一条评论的所有博客文章。到 这样做,您可以将关系的名称传递给 has 方法:

// Retrieve all posts that have at least one comment...
$posts = App\Post::has('comments')->get();

您还可以指定运算符和计数以进一步自定义 查询:

// Retrieve all posts that have three or more comments...
$posts = Post::has('comments', '>=', 3)->get();

嵌套的 has 语句也可以使用“点”表示法构造。 例如,您可以检索至少有一条评论的所有帖子 并投票:

// Retrieve all posts that have at least one comment with votes...
$posts = Post::has('comments.votes')->get();

如果你需要更多的力量,你可以使用 whereHas 和 orWhereHas 将“where”条件放在您的查询上的方法。这些方法 允许您将自定义约束添加到关系约束, 比如查看评论内容:

// Retrieve all posts with at least one comment containing words like foo%
$posts = Post::whereHas('comments', function ($query) {
    $query->where('content', 'like', 'foo%');
})->get();

回答

对于您的具体示例,可以通过以下方式实现:

Foo::has('highBars')->get();

【讨论】:

  • 虽然使用 Foo::has('highBars')->get(); 并不会检索关系。并使用Foo::has('highBars')->with('Bars')->get(); 再次检索所有结果。那么使用Foo::has('highBars')->with('highBars')->get(); 正确吗?似乎是多余的
【解决方案2】:

这还不够。当你定义你的关系时,你只需告诉 Laravel 哪些数据与实体相关联,但它不会限制如何获取数据。

所以当你在你的控制器中这样做时

Foo::with('highBars')->get();

这里的关键是get。你不会将它限制在任何东西上,你只是说,给我你所有的行,除此之外,获取与这个模型相关的数据。您需要做的是添加一个约束。

Foo::with('highBars')->whereHas('highBars', function ($query) {
    $query->where('val', '>', '200');
})->get();

或者一个捷径是

Foo::has('highBars')->get();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 2021-09-20
    • 2020-01-08
    • 2015-10-20
    • 1970-01-01
    • 2020-05-26
    • 2019-02-21
    相关资源
    最近更新 更多