Laravel Eloquent 基于 id 数组检索多行的 ORM 方法

Laravel Eloquent ORM method for Retrieving Multiple Rows based on an Array of ids

我可能没有按照我想要的方式来表达问题,但这是我的困境:

我有 table 个名为 'clients' 的用户,其结构如下:

<style type="text/css">
.tg  {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg .tg-yw4l{vertical-align:top}
</style>
<table class="tg">
  <tr>
    <th class="tg-yw4l">id</th>
    <th class="tg-yw4l">int(10)</th>
    <th class="tg-031e">unsigned</th>
  </tr>
  <tr>
    <td class="tg-yw4l">client_name</td>
    <td class="tg-yw4l">varchar(255)</td>
    <td class="tg-yw4l"></td>
  </tr>
  <tr>
    <td class="tg-yw4l">id_number</td>
    <td class="tg-yw4l">int(11)</td>
    <td class="tg-yw4l"></td>
  </tr>
  <tr>
    <td class="tg-yw4l">email</td>
    <td class="tg-yw4l">varchar(255)</td>
    <td class="tg-yw4l"></td>
  </tr>
</table>

我有另一个 table 政策 'policies' 具有以下结构:

<style type="text/css">
.tg  {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg .tg-yw4l{vertical-align:top}
</style>
<table class="tg">
  <tr>
    <th class="tg-yw4l">id</th>
    <th class="tg-yw4l">int(10)</th>
    <th class="tg-yw4l">unsigned</th>
    <th class="tg-031e">AUTO INCREMENT</th>
  </tr>
  <tr>
    <td class="tg-yw4l">client_id</td>
    <td class="tg-yw4l">int(10)</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
  </tr>
  <tr>
    <td class="tg-yw4l">type_id</td>
    <td class="tg-yw4l">int(11)</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
  </tr>
  <tr>
    <td class="tg-yw4l">product_id</td>
    <td class="tg-yw4l">int(11)</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
  </tr>
</table>

'policies'table中的'client_id'相当于'clients'table中的'id'。一个客户端可以有多个'policies'。当政策过期时,我想获取政策过期的客户列表。逻辑不是每个用户都会有一个过期或过期的策略,但一个用户可以有多个过期和过期的策略。 (例如,在 10 个客户端的 table 中,总共有 20 个过期或过期的策略,可以有 5 个客户端具有过期或过期的策略等)每个策略都与一个客户端相关联。该客户可以拥有无​​限数量的政策

考虑到客户的 'id' 等于政策 table 中的 'client_id',我应该如何计算政策到期的客户数量?

这是我到目前为止尝试过的方法:

$today = Carbon::today()->toDateString();
$yesterday = Carbon::yesterday()->toDateString();
$expiry_period = Carbon::today()->addDays(3)->toDateString();

$client = DB::table('clients')->join('active_policies', 'clients.id', '=', 'active_policies.client_id')->select('clients.id');
$active_clients = Clients::all();

$policies = ActivePolicies::all();
$total_policies = $policies->count();

$expiring = $policies->where('renewal_date', '<=', $expiry_period)->where('renewal_date', '>=', $today);
$total_expiring = $expiring->count();

$expired = $policies->where('renewal_date', '<=', $yesterday);
$total_expired = $expired->count();

//here's where I try to count the clients with expiring policies.
$with_expiring = $expiring->where('client_id', '=', DB::table('clients')->get('clients.id'))->count();

//here's where I try to count the clients with expired policies.
$with_expired = $expired->where('client_id', '=', DB::table('clients')->get('clients.id'))->count();

执行时出现以下错误:

类型错误:传递给 Illuminate\Database\Grammar::columnize() 的参数 1 必须是数组类型,给定的字符串,在 /var/.../app/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.[=54= 中调用] 第 131 行

DB::table('clients')->get('clients.id') returns Collection$expired->where('client_id', '=', '<this should be string>')

尝试:$expiring->where('client_id', '=', DB::table('clients')->get('clients.id')->first())->count()

但是该代码不会提供您想要的。

您应该创建 Eloquent 模型并使用它,而不是使用 DB Facades 编写查询。

请参阅此处了解如何定义 Eloquent 模型 https://laravel.com/docs/5.4/eloquent#defining-models

定义 Client Eloquent 模型后,您可以通过以下方式检索所有客户端:

$clients = Client::whereIn('id', [1, 2, 3]); // where 1,2,3 is the client ids

这似乎可以解决问题:

/*groups the expiring policies for each user*/
$with_expiring = $expiring->groupBy('client_id');

/*counts the number of clients with expiring policies instead of
 *counting the number of expiring policies first then checking
 *against a list of 'client_id's
 */
$total_with_expiring = $with_expiring->count();

/*groups the expired policies for each user*/
$with_expired = $expired->groupBy('client_id');

/*counts the number of clients with expired policies instead of
 *counting the number of expired policies first then checking
 *against a list of 'client_id's
 */
$total_with_expired = $with_expired->count();

仍然存在确保 'client_id' 与客户端 table 中的 'id' 真正匹配的问题。