Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

garrettmassey's avatar

Polymorphic relationship querying help

I'm having trouble wrapping my head around this specific relationship type in Laravel / Eloquent.

In my app, there are the following models: Document, Directory, User, Team, JobTitle, Department.

A user has many documents and directories, a document belongs to a directory.

The issue that I am having comes with the sharing of documents and directories. The policy is set up so that only the owner of the document / directory can view that item. But I want to set up a shared_items table, that way, a user can share a document, or can share a directory (and subsequently its contents) with any number of Users, Teams, JobTitles, or Departments.

Then, when checking if a user can view the document, the policy will see if the document / directory has been shared with the user specifically ($user->sharedItems) or if it has been shared with the team ($user->team->sharedItems) etc. And the document can also show who it has been shared with: $document->sharedWith

So the table structure I have is like so:

Schema::create('shared_items', function (Blueprint $table) {
            $table->id();

            // the type of item being shared
            $table->string('shared_item_type');
            // the ID of the item being shared
            $table->unsignedBigInteger('shared_item_id');

            // the type of model the item is being shared with
            $table->string('shared_with_type');
            // the ID of the model the item is being shared with
            $table->unsignedBigInteger('shared_with_id');

            // the ID of the user who shared the item
            $table->unsignedBigInteger('shared_by');
            $table->foreign('shared_by')
                      ->references('id')
                      ->on('users')
                      ->cascadeOnDelete();

            // the date and time the item was shared, exp date
            $table->timestamp('expires_at')->nullable();
            $table->timestamps();
        });

I created a SharedItem intermediate model:

class SharedItem extends MorphPivot
{
    protected $table = 'shared_items';

    protected $fillable = [
        'shared_by',
        'shared_item_type',
        'shared_item_id',
        'shared_with_type',
        'shared_with_id'
    ];

// The model that the shared item is related to
    public function sharable(): MorphTo
    {
        return $this->morphTo('item');
    }

    // The model that the item is shared with
    public function sharedWith(): MorphTo
    {
        return $this->morphTo('shared_with');
    }

    // The user who shared the item
    public function sharedBy()
    {
        return $this->belongsTo(User::class, 'shared_by');
    }
}

and in my Document model, I have this:

    public function sharedWith(): MorphToMany
    {
        return $this->morphToMany(SharedItem::class, 'shared_item');
    }

and in my Team model (which I am using to test) I have this:

    public function sharedItems()
    {
        return $this->morphMany(SharedItem::class, 'shared_item');
    }

But the relationship doesn't seem to work. I've tweaked it around a bit with the naming conventions (it's all getting mixed up in my head), but I either get that a column '' does not exist error, or no errors but nothing populates the table.

$testDoc->sharedWith()->sync(Team::first()); results in:

error: SQLSTATE[42S22]: Column not found: 1054 Unknown column '' in 'field list' (Connection: mysql, SQL: insert intoshared_items(``,shared_item_id, shared_item_type) values (1, 5, App\Models\Document)),

here, it also looks like it's only storing half of the data needed to make the relationship, it's storing the item_id and the item_type, but nothing about the other model.

I've been at this for hours, so my mind is fried, and I'm sure I'm missing something straightforward. Any help would be appreciated!

0 likes
0 replies

Please or to participate in this conversation.