Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Laravel查询具有急切加载条件的多对多记录_Php_Sql_Laravel_Eloquent - Fatal编程技术网

Php Laravel查询具有急切加载条件的多对多记录

Php Laravel查询具有急切加载条件的多对多记录,php,sql,laravel,eloquent,Php,Sql,Laravel,Eloquent,所以我的应用程序有这样的结构 付款有多个付款人 付款人属于用户(用户有许多付款人) 我想查询特定用户ID的所有付款(和透视数据)。我一直在使用此查询返回所有付款,而不管用户ID: $payment_data = Payment::with('payers')->get(); 现在,如果我只想获得付款人的用户id为(比如)5的付款,我尝试了以下方法: $payment_data = Payment::with(array( 'payers' => function

所以我的应用程序有这样的结构

  • 付款有多个付款人
  • 付款人属于用户用户有许多付款人
我想查询特定用户ID的所有付款(和透视数据)。我一直在使用此查询返回所有付款,而不管用户ID:

$payment_data = Payment::with('payers')->get();
现在,如果我只想获得付款人的用户id为(比如)5的付款,我尝试了以下方法:

$payment_data = Payment::with(array(
        'payers' => function($q){
           $q->where('user_id', '=', 5);
        }))->get();
但它返回几乎相同的结果,除了条件仅适用于付款人,而不适用于付款,即如果未满足
用户id
条件,我仍然获得付款表中的所有付款,只是不适用于透视数据。从技术上讲,我可以只使用这个结果,过滤掉
付款人
子数组为空的结果,但如果支付量很大,这将变得非常低效

形成此查询的正确方式是什么

编辑 以下是我的数据库结构的基本表示:

简单的SQL查询应该是这样的(RDMS各不相同,但您可以理解):

使用wherehas可得出以下结果:

SELECT * 
FROM   "payments" 
WHERE  (SELECT Count(*) 
        FROM   "payers" 
               INNER JOIN "payer_payment" 
                       ON "payers"."id" = "payer_payment"."payer_id" 
        WHERE  "payer_payment"."payment_id" = "payments"."id" 
               AND "payers"."user_id" = '1') >= '1' 
这不是我想要的

编辑2 好的,经过多次修改,我知道我需要使用渴望加载,因为我需要透视字段以及支付模型本身的字段。下面的示例显示了3笔付款及其数据透视:

Array
(
    [0] => Array
        (
            [id] => 2
            [payment_date] => 2014-03-07
            [company] => Franco Manca
            [item] => Pizza
            [created_at] => 2014-03-10 10:16:08
            [updated_at] => 2014-03-10 10:16:08
            [payers] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [name] => tim
                            [email] => tim@tim.com
                            [user_id] => 1
                            [created_at] => 2014-03-10 10:07:23
                            [updated_at] => 2014-03-10 10:07:23
                            [pivot] => Array
                                (
                                    [payment_id] => 2
                                    [payer_id] => 1
                                    [amount] => 21.0
                                    [pays] => 0
                                    [created_at] => 2014-03-10 10:16:08
                                    [updated_at] => 2014-03-10 10:27:45
                                )

                        )

                    [1] => Array
                        (
                            [id] => 2
                            [name] => tom
                            [email] => tom@tom.com
                            [user_id] => 1
                            [created_at] => 2014-03-10 10:16:35
                            [updated_at] => 2014-03-10 10:16:35
                            [pivot] => Array
                                (
                                    [payment_id] => 2
                                    [payer_id] => 2
                                    [amount] => 0.0
                                    [pays] => 1
                                    [created_at] => 2014-03-10 10:27:45
                                    [updated_at] => 2014-03-10 10:27:45
                                )

                        )

                )

        )

    [1] => Array
        (
            [id] => 3
            [payment_date] => 2014-03-05
            [company] => Kaff
            [item] => Cocktail
            [created_at] => 2014-03-10 10:17:05
            [updated_at] => 2014-03-10 10:17:05
            [payers] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [name] => tim
                            [email] => tim@tim.com
                            [user_id] => 1
                            [created_at] => 2014-03-10 10:07:23
                            [updated_at] => 2014-03-10 10:07:23
                            [pivot] => Array
                                (
                                    [payment_id] => 3
                                    [payer_id] => 1
                                    [amount] => 12.0
                                    [pays] => 1
                                    [created_at] => 2014-03-10 10:17:05
                                    [updated_at] => 2014-03-10 10:17:05
                                )

                        )

                    [1] => Array
                        (
                            [id] => 2
                            [name] => tom
                            [email] => tom@tom.com
                            [user_id] => 1
                            [created_at] => 2014-03-10 10:16:35
                            [updated_at] => 2014-03-10 10:16:35
                            [pivot] => Array
                                (
                                    [payment_id] => 3
                                    [payer_id] => 2
                                    [amount] => 19.0
                                    [pays] => 1
                                    [created_at] => 2014-03-10 10:17:05
                                    [updated_at] => 2014-03-10 10:17:05
                                )

                        )

                )

        )

)
问题是,如果我随后将user_id条件更改为,比如99999(不存在),它仍然返回所有付款,并且每个付款方的
数组都是空的,而实际上它应该返回一个完全空的结果

为即时加载生成的两个查询是:

select * from "payments" --I want to add my user_id condition to this

使用的方法仅用于加载关系,该关系上的约束应设置为:

$payment_data = Payment::whereHas('payers', function($q){
           $q->where('payers.user_id', '=', 5);
        })->get();
);
还可以指定要在where子句中使用的变量:


试着用另一种方法来做

User::find(5)->with('payers.payments')->get();

您将拥有一个包含付款人及其付款的类,以便获得循环付款人所需的所有信息,我认为joins可以完美地完成这项工作,因为您不需要循环。

好的,经过广泛搜索,a我得到了答案:

您首先需要使用whereHas
,仅为所需用户获得付款:

$payments = Payment::whereHas('payers', function($q){
    $q->where('user_id', '=', Auth::user()->id); 
},'>=', DB::raw('1'))->get();
然后,您不需要在整个
支付
模型上调用即时加载,而只需在您刚刚进行的支付收款上调用它(延迟即时加载):


这会将pivot数据添加到$payments集合中,为您提供所需的信息,而无需查询数据库中的每一笔付款(这是问题中的第一个方法所做的)。

我认为这不正确,因为这只是添加了一个子查询,用于确定布尔结果(如果我们可以找到一些用户ID为5的付款人,请返回所有付款). 查询应该连接表并添加条件。上面添加了更多详细信息。在发布之前,我使用类似的模型测试了查询,它只返回带有付款人条件的付款。我在模型上测试了查询,结果为空。请参见上面的编辑关于此内容:Payment::with('payers')->join('payers','Payment.id','=','payers.id')->其中('payers.user_id','=',5)->get(),确定我检查了编辑问题,至少你会知道如何在相关模型中使用join子句来调整它以适应你的模型。这似乎是在做某种无限循环操作,但最后忘了添加get()方法。
$payment_data = Payment::whereHas('payers', function($q) use ($foo){
           $q->where('payers.user_id', '=', $foo);
        })->get();
);
User::find(5)->with('payers.payments')->get();
$payments = Payment::whereHas('payers', function($q){
    $q->where('user_id', '=', Auth::user()->id); 
},'>=', DB::raw('1'))->get();
$payment_data = $payments->load(array(
    'payers' => function($q){
       $q->where('user_id', '=', Auth::user()->id);
}));