2013-08-11 3 views
2

J'ai un modèle complexe avec plusieurs relations définies. Dans cet exemple, je voudrais compter le modèle Like et créer une propriété nommée likes afin qu'il puisse être renvoyé à partir d'un service REST.laravel 4 éloquent impatient load relation nombre

Est-il possible de charger rapidement un compte de modèle dans une propriété dynamique?

$beat = Post::with(
     array(
      'user', 
      'likes' => function($q){ 
       $q->count(); 
      } 
     )) 
     ->where('id', $id) 
     ->first(); 

Répondre

1

Vous devez utiliser l'instruction SQL Group By afin de rendre cela fonctionne. Vous pouvez réécrire votre requête comme la suivante. Le résultat likes est un objet Collection avec un élément. Je suppose que la relation entre le modèle Post et Like est PosthasManyLike. Donc, vous pouvez accéder au compte comme ça.

$beat->likes->first()->like_count; 

Je n'ai pas testé le code ci-dessus mais cela devrait fonctionner.

+0

Le code que vous avez fourni ne fonctionne pas. Le nombre like_count n'est pas défini – edi9999

+0

@ edi9999, il doit être défini par Laravel à la volée puisqu'il a été rempli en tant que colonne. Jetez un oeil à: DB :: raw ("count (*) as like_count") – rioastamal

+0

@ edi9999 J'essaie de faire quelque chose de similaire, mais ça ne fonctionnait pas quand le compte était 0 (depuis 'first() 'renvoie null). Pour faire face à ce cas particulier, j'ai fait ceci: '$ beat-> likes-> first()? $ beat-> aime-> first() -> like_count: 0'. Peut-être que vous avez eu le même problème? –

4

En supposant que vous avez Post->hasMany->Like relation et vous avez déclaré aime relation comme:

class Post{ 

    public function likes(){ 
    return $this->hasMany('Like'); 
    } 
} 

créer une nouvelle fonction disent likeCountRelation que:

public function likeCountRelation() 
{ 
    $a = $this->likes(); 

    return $a->selectRaw($a->getForeignKey() . ', count(*) as count')->groupBy($a->getForeignKey()); 
} 

vous pouvez désormais remplacer __get() fonction:

public function __get($attribute) 
{ 

    if (array_key_exists($attribute, $this->attributes)) { 
     return $this->attributes[$attribute]; 
    } 

    switch ($attribute) { 

     case 'likesCount': 
      return $this->attributes[$attribute] = $this->likesCountRelation->first() ? $this->likesCountRelation->first()->count : 0; 
      break; 

     default: 
      return parent::__get($attribute); 

    } 
} 

ou vous pouvez utiliser la fonction getattribute comme:

public function getLikesCountAttribute(){ 
return $this->likesCountRelation->first() ? $this->likesCountRelation->first()->count : 0; 
} 

et simplement accéder likesCount comme $post->likesCount vous pouvez charger même hâte qu'il aime:

$posts=Post::with('likesCountRelation')->get(); 
foreach($post as $post){ 
    $post->likesCount; 
} 

NOTE: logique même peut être utilisé pour de nombreuses relations morphing.

Questions connexes