繁体   English   中英

Laravel查询生成器,哪里基于条件?

[英]Laravel Query Builder, Where based on condition?

我有一个下拉列表来选择一个父对象,它是对页面的自引用。 我想限制该下拉列表的结果,因此它不允许我将一个Page嵌套多个级别。

如果我编辑'儿子'页面,而'儿子'有一个'孙子',我不应该被允许选择'爸爸'作为儿子的父母,因为它会创建一个深的巢

在下面的例子中,当我编辑Son记录时,我不应该选择爸爸作为它的父亲,因为儿子有孩子。

+----+-----------+----------+
| id | parent_id |  title   |
+----+-----------+----------+
|  1 | NULL      | Dad      |
|  2 | NULL      | Son      |
|  3 | 2         | Grandson |
+----+-----------+----------+

现在在这种情况下,我应该能够在编辑Son记录时选择Dad作为父亲,因为Son没有任何孩子

+----+-----------+----------+
| id | parent_id |  title   |
+----+-----------+----------+
|  1 | NULL      | Dad      |
|  2 | NULL      | Son      |
|  3 | NULL      | Grandson |
+----+-----------+----------+

我正在努力解决这个问题,以及如何将这一切包装在查询构建器中。

到目前为止我有什么

如果Son有一个自己的Child,下面的代码可以工作,我将无法选择Dad,这很好。 但是在没有孩子的情况下失败了。

归结为:我的父选择还应该允许显示parent_id为null的页面,但前提是当前记录(Son)没有任何子项。

回顾:只显示记录,如果它没有出现在任何parent_id中,所以没有子节点,如果没有,但是没有要显示的记录..如果没有,它应该显示parent_id为空的记录。 这可能在一个查询中?

$query->where('id', '<>', $page->id);
$query->where('parent_id', '<>', $page->id);

您需要自己加入表,因为where子句是每行。

使用左连接将表连接到自身,其中ID与父ID匹配。 然后仅选择连接表的ID为空的行。

$pages = DB::table('pages AS p')
            ->leftJoin('pages AS p1', 'p.id', '=', 'p1.parent_id')
            ->where('p.id', '<>', $page->id)
            ->whereNull('p1.id')
            ->select('p.*')
            ->get();

您可以使用whereRaw函数查询构建器子查询来检查代码

$result = DB::table('parents as p')
    ->whereRaw("parent_id is null and id not in (SELECT parent_id FROM parents WHERE parent_id is not null)")
    ->get();
dd($result);

o / p看起来像这样
第一种情况

在此输入图像描述

第二种情景 在此输入图像描述

它可能会帮助你:)

嗯......我认为不可能将其分解为一行,因为你必须循环parent_id列检查当前id是否在parent_id列中:

但不要担心:一种不同的方法会更容易:两个独立的表,因此不同的关系:

Pages model: has one parent
Parents model: belongs to a page

通过以上关系,您可以轻松地使用eloquent来获取没有父级的东西,只需检查哪里没有给定的关系:

打破这个:

Pages model:

public function parents () {
    return $this->hasOne(Parent::class, 'page_id');
}

给父母模特:

 Parents model:

 protected $fillable = ['page_id'];

 public function pages () {
     return $this->belongsTo(Page::class, 'page_id');
 }

您可以在Page模型中创建父子关系。

public function parent()
{
    return $this->belongsTo('Page', 'parent_id');
}

public function children()
{
    return $this->hasMany('Page', 'parent_id');
}

现在,您可以检查Page是否有子项,并选择父ID为null的记录,如下所示:

$pages = Page::where('parent_id', null)->doesntHave('children')->get();

这将为您提供父ID为null且没有子项的记录。 我希望你明白。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM