skip to Main Content

I am using Laravel 11 and the following structure:

users
 - id

artworks
 - id

collections
 - id

collection_user
 - id
 - collection_id
 - user_id

artwork_collection
 - id
 - artwork_id
 - collection_id

So a User can have multiple Collections, a Collection can belong to multiple Users and an Artwork can be in several Collections. I hope with that in mind the structure and models are setup correctly:

<?php

class Artwork extends Model
{
    public function collections(): BelongsToMany
    {
        return $this->belongsToMany(Collection::class)->withTimestamps();
    }
}

class Collection extends Model
{
    public function artworks(): BelongsToMany
    {
        return $this->belongsToMany(Artwork::class)->withTimestamps();;
    }

    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class)->withTimestamps();;
    }
    
}

class User extends Authenticatable
{
    public function collections(): BelongsToMany
    {
        return $this->belongsToMany(Collection::class)->withTimestamps();
    }
}

?>

How does the artworks() relation function need to be defined in the User model in order to get all Artworks a User has through Collections?

I tried using the hasManyThrough relation but it requires the artworks and collections tables to have direct references to users.

public function artworks(): HasManyThrough
{
    return $this->hasManyThrough(Artwork::class, Collection::class);
}

Do I need to add a pivot model? Do I need to join something?

2

Answers


  1. Chosen as BEST ANSWER

    After some fiddling (and help from AI) I came up with this. I dont know if that is best practice and would love to know the actual Laravel approach for this (if it isnt already):

    public function artworks()
    {
        return $this->belongsToMany(Artwork::class, 'collection_user', 'user_id', 'collection_id')
            ->join('artwork_collection AS ac', 'collection_user.collection_id', '=', 'ac.collection_id')
            ->join('artworks AS aw', 'ac.artwork_id', '=', 'aw.id')
            ->distinct()
            ->withTimestamps();
    }
    

  2. Wouldn’t the type of relationship you need be Many to Many?

    See the Eloquent documentation for this type of relationship. There are examples of the structure that models should have.

    Laravel Doc

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search