2012-11-02 106 views
27

我是新来laravel和雄辩,我不知道这是甚至可能的。但我有两个表,一对多的关系。一个是“位置”,一个是“用户”。一个位置可以有许多用户。Laravel雄辩数数关系

所以,如果我想获得所有用户的所有位置,我只想做:

Location::with("users")->get(); 

但我也想知道有多少用户每个位置了,我试着这样做

Location::with("users")->count("users")->get(); 

但这并没有奏效。

+0

你做了什么迄今为止发现的?我的意思不是有人建议你已经做了什么。 – hakre

+0

如果一直在检查文档,但无法找到任何相关信息 – Arcade

+0

如果'Location :: with(“users”) - > get();'Location :: with(“users”) - > count() ;'也可以工作。你有没有试过(我刚刚扫描了文档,从来没有使用过这个库)? – hakre

回答

34

如果您使用预先加载,则不会出现提到的n + 1问题。

$locations = Location::with('users')->get(); 

$locations->users()->count(); 

无论您拥有多少用户或位置,这应导致三个查询。其中

混乱对选址模型

  • SELECT * FROM位置
  • SELECT * FROM用户

    • 数查询产生的事实,这也适用:

      $locations = Location::all(); 
      
      $locations->users()->count(); 
      

      但是在这种情况下,它会为每个位置查询一次。

      查看文档的更多信息: http://laravel.com/docs/eloquent#eager-loading

  • +9

    尽管派对迟到了,就像指出你仍然得到这个n + 1的问题。你需要在foreach中使用'$ location> users-> count()',基本上不访问方法users(),但访问属性,或者每次都执行查询。 – David

    +0

    @David非常感谢你,你帮我解决了困惑,因为我仍然看到了n + 1问题。这将有助于更新此答案以更准确。 –

    7

    你需要调用每个位置记录的计数方法来获取用户的每个位置算,这里有一个例子:

    foreach(Location::get() as $location) // or foreach(Location::with("users")->get() as $location) 
    { 
        echo $location->users()->count(); 
    } 
    

    这应该解决您的问题,给你按每个位置的用户数量。您可以在循环中添加一个检查来忽略用户数为0的位置。

    +6

    这会使用与Location :: get()的结果一样多的DB查询吗? –

    +32

    这很糟糕。它导致[n + 1查询问题](http://stackoverflow.com/questions/97197/what-is-the-n1-selects-issue?lq=1) – edi9999

    +0

    在这种情况下,使用Collection更好。因为这样你使用PHP来进行关系计数。 '$ location-> users-> count()' –