【问题标题】:laravel nested hasmany with where clause on last childlaravel 嵌套 hasmany 与最后一个孩子的 where 子句
【发布时间】:2021-11-04 10:23:19
【问题描述】:

我想从与最后一个孩子的 where 子句的嵌套关系中获取数据(作为 json 嵌套响应)。我正在制作一个包含 4 个嵌套模型的 API,这些模型有很多这样的关系: 模型A->hasmany模型B->hasmany模型C->hasmany模型D (modelA 是第一个父级等)

我在 api.php 上有一个路由

Route::get('/rdata/{string}', [ModelAController::class, 'getdata']);

在我的 ModelAController 上:

public function getdata($string)
{
    return ModelA::thedata($string);
}

然后在我的 ModelA 上

public static function thedata($string)
{ 
    return ...
}

我想根据第 4 个 ModelD 的字段获取数据。我怎样才能对第四个孩子做一个 where 子句可能是这样的:

where('column', 'like', '%'.$string.'%')

我也尝试使用集合资源,我可以很好地嵌套所有数据,但我无法对最后一个孩子执行我想要的查询。我取得的最好成绩是对最后一个子负载父母进行查询,但它不能正常工作

return ModelD::where('column', 'like', '%'.$string.'%')->with('modelc.modelb.modela')->get();

甚至有负载

return ModelD::where('column', 'like', '%'.$string.'%')->get()->load('modelc.modelb.modela');

然后在 ModelC 上:

public function modelb()
{
    return $this->belongsTo(ModelB::class, 'f_key','f_key');
}

对于其他父母也是如此,但这是错误的,因为我再次将所有孩子都放入其中,而且 json 也是反转的。我想保留格式:

 $response = ['ModelA' => [
                            'id' => '..'
                            'field1' => '..'
                            'ModelB'=>[
                                etc..
                            ]]

或者还有其他我看不到的方法吗?在某种程度上,我需要这样的东西,但在嵌套的 json 中格式化

return DB::table('modela')
->join('modelb', 'modela.id', 'modelb.modela_id')
->join('modelc', 'modelb.id', 'modelc.modelb_id')
->join('modeld', 'modelc.id', 'modeld.modeld_id')
->where('column', 'like', '%'.$string.'%')
->get();

Edit1:到目前为止,我根据答案得到了这个,我想获得最后一个孩子的父列

return self::with('modelb.modelc.modeld')-> whereHas('modelb.modelc.modeld', function ($modeld) use ($string) {
    $modeld->where('column', 'like', "%$string%");
    ->whereColumn('modelc.column2', 'modeld.column2')
    ->whereColumn('modelc.column3', 'modeld.column3');
})
->with(['modelb.modelc.modeld' => function ($modeld) use ($string) {
    $modeld->where('column', 'like', "%$string%");
    ->whereColumn('modelc.column2', 'modeld.column2')
    ->whereColumn('modelc.column3', 'modeld.column3');
}])
->get();

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    我认为您可以使用 whereHas/with Closures 做到这一点。

    ModelA::query()
        ->whereHas('modelb.modelc.modeld', function ($modeld) use ($string) {
            $modeld->where('column', 'like', "%$string%");
        ->with(['modelb.modelc.modeld' => function ($modeld) use ($string) {
            $modeld->where('column', 'like', "%$string%");
        }])
        ->get();
    

    类似的东西,但在条件下可能更精致。


    根据您的编辑,我认为此查询应该可以满足您的需求。

    ModelA::query()
        ->whereHas('modelb.modelc', function ($modelC) use ($string) {
            $modelC->whereHas('modeld', function ($modelD) use ($string) {
                $modelD->whereColumn('table_c.column2', 'table_d.column2')
                       ->whereColumn('table_c.column3', 'table_d.column3')
                       ->where('table_d.column', 'like', "%$string%");
            });
        ->with(['modelb.modelc' => function ($modelC) use ($string) {
            $modelC->with(['modeld' => function ($modelD) use ($string) {
                $modelD->whereColumn('table_c.column2', 'table_d.column2')
                       ->whereColumn('table_c.column3', 'table_d.column3')
                       ->where('table_d.column', 'like', "%$string%");
            }]);
        }])
        ->get();
    

    【讨论】:

    • 这似乎很有帮助,但是如何在 modelC 和 modelD 的列的查询中使用 wherecolumn? ->whereColumn('modelC.column', 'modelD.column')
    • 您可以发布您尝试进行的整个查询吗? whereHas 应该自己处理加入条件,但如果您的查询还有其他内容,我可以编辑我的答案
    • 如果字符串等于建模上的列,但列2和列3等于父模型c,我想获得结果。我将用代码编辑问题
    • 我尝试了类似的方法,您的回答在这两种情况下都找不到 1054 列,在我的模型上我返回 this->hasmany(Child::class, 'fkey','lkey'),我错过了什么吗?
    • 您尝试过滤的列是否存在于数据库表中,或者它们是访问器(getColumnAttribute 函数)?
    猜你喜欢
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 2017-01-03
    • 2021-07-05
    • 2019-04-03
    • 1970-01-01
    • 2016-11-23
    相关资源
    最近更新 更多