1

I would like to chain 2 global scopes which are accessible through traits I made.

trait ActivatedTrait
{
    public static function bootActivatedTrait()
    {
        static::addGlobalScope(new ActivatedScope);
    }

    public static function withInactive()
    {
        $instance = new static;
        return $instance->newQueryWithoutScope(new ActivatedScope);
    }
}

trait PublishedTrait
{
    public static function bootPublishedTrait()
    {
        static::addGlobalScope(new PublishedScope);
    }

    public static function withUnpublished()
    {
        $instance = new static;
        return $instance->newQueryWithoutScope(new PublishedScope);
    }
}

When I call my model like this, it works

MyModel::withInactive()
MyModel::withUnpublished()

But this doesn't

MyModel::withInactive()->withUnpublished()

EDIT

For some reason, this code worked under Laravel 4.2, but I switched to 5.5 and now it broke.

EDIT 2

If I make local scopes like scopeWithInactive() and scopeWithUnpublished() I can chain them just fine.

Norgul
  • 4,613
  • 13
  • 61
  • 144

1 Answers1

2

Since I was new to the project, I didn't quite understand what was being done since I didn't have the needed insight after that part broke after upgrade. What I did was:

Eliminate traits, added normal L 5.5 global scopes (this one fetches only active items with each request)

class ActivatedScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $builder->where('content.is_active', 1);
    }
}

Booted them up in model

protected static function boot()
{
    parent::boot();
    static::addGlobalScope(new ActivatedScope());
    static::addGlobalScope(new PublishedScope());
}

And added local scopes which would cancel the effect of it:

public function scopeWithInactive($query)
{
    return $query->withoutGlobalScope(ActivatedScope::class);
}

This enabled me to do this:

Item::all() // <- only active and published items

Item::withInactive()->get() // <- published items which are either active or inactive

Item.:withInactive()->withUnpublished()->get() // <- all items from DB

NOTE

My initial question was wrong as there is no point in "chaining" anything here since global scopes are applied to the model automatically. If I use 2 global scopes, both are applied. So it was a matter of chaining functions which would disable the effect of global scope.

Norgul
  • 4,613
  • 13
  • 61
  • 144