CorvS's avatar
Level 27

Count One-To-One to One-To-Many relationship

Hey there!

I am new to Laravel and have difficulties to get my Eloquent queries right. I don't really understand when to use what query and it what order, when querying over multiple relations.

My model looks like that (simplified):

Imgur (Zoom in to see the relations)

Due to the One-To-Many relation between Profile and Interest another table is created (in the database):

Imgur

What I would like to achieve is a query which gives me the count for each interest, so I am able to see what users are most interested in, e.g.:

name | count

Movies | 5

Books | 3

I think you get it | 2

My "problem" is most likely trivial, but as I said I am a bit overwhelmed by Eloquent right now.

Any help would be much appreciated.

Best,

Nim

PS: Is it possible to show images from Imgur via Markdown directly?

0 likes
4 replies
mykolayakovchuk's avatar

I described special method in model for this. In this examle I have post table, and connected table with columns: id, id_post, id_user. So I see every user who press like.

My model for Post have connection to likes:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model;

class Post extends Model { use HasFactory;

/**
 * Таблица БД, ассоциированная с моделью.
 * 
 * @var string
 */
protected $table = 'post';

//....
/**
 * get collection of likes.
 * @return collection
 */
public function Likes(){
    return $this->hasMany(Like::class, 'id_post');
}
 /**
 * Сосчитать количество лайков. Count number of likes.
 * @return number
 */
public function countLikes(){
    return $this->Likes->count();
}

}

Then I just call this method from Controller, and it returns me a number.

class PostController extends Controller { ////......

/**
 * function take post header by id
 * 
 * @param int
 * @return Array
 */
public function getPostHeadById($idPost){
    $postHeader = Post::find($idPost);

//..

    return [ 
        "postHeader" => $postHeader, 
        "Likes" => $postHeader->countLikes(),
    ];
}

}

OUTPUT IN BROWSER (dd()):

array:3 [▼

"postHeader" => App\Models\Post {#1291 ▶}

"postAuthor" => App\Models\UserInfo {#1292 ▶}

"Likes" => 0

]

mykolayakovchuk's avatar

And today I find another way to solve this. Count number without loading:

public function Likes(){
    return $this->hasMany(Like::class, 'id_post');
}

/**
 * Сосчитать количество лайков. Count number of likes.
 * @return number
 */
public function countLikes($idPost){
    $postCollection = $this->where('id', $idPost)->withCount('likes')->get();
    return $postCollection[0]->likes_count;           
}

And in Controller:

public function getPostHeadById($idPost){
    $postHeader = Post::find($idPost);
    $postAuthor = UserInfo::find($postHeader->id_user);
    return [ 
        "postHeader" => $postHeader, 
        "postAuthor" => $postAuthor,
        "Likes" => $postHeader->countLikes($idPost),
    ];
}

I think this way better, becouse it count models without loading. Hope this will help somebody

Please or to participate in this conversation.