雄辩的ORM渴望加载多对多关系中的独特记录

时间:2013-08-23 12:39:55

标签: laravel laravel-4 eloquent

背景

我有一个List模型,它属于并拥有许多订阅者。当然还有一个属于并拥有许多List的订阅者。

问题

我想从多个列表中急切加载所有订阅者。但是,我只对不同的订阅者感兴趣,因为订阅者可以拥有并且确实属于多个列表。

我的尝试

我使用了distinct()方法,但这并没有产生任何乐趣。我也可以遍历结果集来手动切出重复项。只是想知道是否有办法让Laravel为我做肮脏的工作?

代码

    $lists = Input::get('listsarray');

    $addresses = Addressbook::with(array('subscribers' => function($query)
                    {
                        $query->where('active', '=', 1);
                        // $query->distinct(); //This didn't work
                    }))->whereIn('id', $lists)->get();

1 个答案:

答案 0 :(得分:5)

通过加入

检索唯一订阅者

我会尽量使用Lists而不是Adressbook来解释它,因为我无法理解您的模型,这可能会引起进一步的混淆。

如果我正确理解了您的评论,那么您正在尝试检索与id IN listarray列表关联的所有唯一订阅者。在这种情况下,Eager Loading不是正确的方法。预先加载用于预加载模型的关联,以便稍后使用它们。在您的情况下,您不会检索Lists及其Subscribers,而是检索唯一的Subscribers

$lists = Input::get('listsarray');

$subscribers = Subscriber::join('list_subscriber', 'list_subscriber.subscriber_id', '=', 'subscribers.id')
    ->whereIn('list_subscriber.list_id', $lists)
    ->groupBy('list_subscriber.subscriber_id')
    ->get(array('subscribers.*'));

如果您还希望检索与此类订阅者关联的所有列表,您可以这样做:

// Simply include a with('lists') and Eloquent will eager load them
$subscribers = Subscriber::with('lists')
    ->join('list_subscriber', 'list_subscriber.subscriber_id', '=', 'subscribers.id')
    ->whereIn('list_subscriber.list_id', $lists)
    ->groupBy('list_subscriber.subscriber_id')
    ->get(array('subscribers.*'));

渴望加载

如果只是改善性能,你不需要使用不同的,Laravel已经做到了。 Eloquent的行为如下:

  1. 获取所有lists
  2. 通过lists构建一个独特的list_ids
  3. 数组来迭代
  4. 使用list_subscribers
  5. 获取所有WHERE list_id IN (X, Y, Z)
  6. 遍历所有list_subscribers构建一个独特的subscriber_id
  7. 数组
  8. 使用subscribers
  9. 获取所有WHERE id IN (X, Y, Z)