Dave Wize's avatar

Adding a global scope on a table on some pivot table condition

Hi Everyone. I'm a beginner, and I'm trying to create a concept for a multi-user chat app. So I have a many to many relationship for the users and channels table so users can create private chat rooms.

Now I wonted to create a global scope to make sure that users cannot access and see other users channels. So I tried to create something like this.

 protected static function booted()
  { 

       static::addGlobalScope('privateChannels', function (Builder $builder) {
            $builder->where('user_id', auth()->user->id)
                ->orWhere('public', true);
        });
    }}

But it is not working as it cannot access the pivot tables columns. Any thoughts on this?

0 likes
12 replies
Sinnbeck's avatar

Can you show some more? The full class and the query that isn't working as expected as well as any errors

Dave Wize's avatar

@Sinnbeck Thanks for your quick reply. Here is the Channel model

<?php

namespace App\Models;

use App\Traits\BelongsToShop;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class channel extends Model
{
    use HasFactory, BelongsToShop;

    protected $fillable = [
        'name',
        'shop_id',
        'public',
    ];

    public function Message()
    {
        return $this->hasMany(Message::class);
    }

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

    protected static function booted()
    {

        static::addGlobalScope('privateChannels', function (Builder $builder) {
            $builder->where('user_id', auth()->user->id)
                ->orWhere('public', true);
        });
    }
}

Nothing major about the user model, and I have created a pivot table called channel_user_table that contains the ID for user and channel.

Dave Wize's avatar

@Sinnbeck You're totally right, I will fix it soon. But can you help me figure out how we can access a pivot property on a global scope (which is a static function)?

Dave Wize's avatar

Already fixed the naming on these two models, will update the full code soon:)

Sinnbeck's avatar

@Dave Wize I don't see any static functions (apart from laravels built in) in the provided code?

Dave Wize's avatar

@Sinnbeck the booted and the global scope are static and therefore I cannot access the pivot by creating a method such as

public function pivot()
{

$pivot = $this->users()->getTable();

}

I'm not sure if I expressed myself clear enough... It is late at night now

Dave Wize's avatar

And here is the SQL error I received

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_id' in 'where clause'
SELECT
  *
FROM
  `channels`
WHERE
  `shop_id` = 1
  AND (
    `user_id` = 1
    OR `public` = 1
  )
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@Dave Wize ok if I understand you correctly

$builder->whereRelation('user', 'id', '=', auth()->user->id)
                ->orWhere('public', true);
        }); 
1 like
Dave Wize's avatar

@Sinnbeck You helped me last time. I have one more question on this. is it possible to go one step forward? Let's say I have a project model and want to do the above query but start from the project.

Basically, I want to filter

project id WHERE channel id HAS user ID

In other words, I want to be able to add another step in the where clause like this

$builder->whereRelation( 'channel', 'user', 'id', '=', auth()->user->id)
                ->orWhere('public', true);
        }); 

Would this work?

I'm not sure If I explained my dilemma clearly enough.

Thanks for your great help. Dave

Please or to participate in this conversation.