Sunday, February 20, 2022

[FIXED] Laravel, create local scope in another class

Issue

I have a model Tasks; i want to create some local scope; we can create it with:

public function scopeIstasked($query){
  return $query;
}

but i want to create it on another file as service cause maybe i can ended with so much scope that my model is not readable anymore

so i create TaskScopeService.php

class TaskScopeService {
    public function showConcerned($query){
        $query = $query->whereHas('organisations.organisateur', function($query){
            $query->where('customers.id', Auth::id());
        });

        return $query;
    }

    public function showToFromAll($query){
        $query = $query->where(function($query){
            $query->where('porter', 'close')->whereHas('customer', function($query){
                $query->isfriend();
            })->whereDoesntHave('group');
        });

        return $query;
    }
}

i want to merge these function into my model that can be used as scope behavior; I just use the simple way that call the class inside my model constructor and use them inside scope function but i end with so much scope function in my model as the situation i didn't want


Solution

Declare the methods inside a trait

trait TaskScopeService {
    public function scopeConcerned($query){
        $query = $query->whereHas('organisations.organisateur', function($query){
            $query->where('customers.id', Auth::id());
        });

        return $query;
    }

    public function scopeToFromAll($query){
        $query = $query->where(function($query){
            $query->where('porter', 'close')->whereHas('customer', function($query){
                $query->isfriend();
            })->whereDoesntHave('group');
        });

        return $query;
    }
}

and then use it in the class Task

class Task extends Model 
{
    use TaskScopeService;
//...
}

to use the a scope function which name start with scope do:

Task::concerned()->get();
//or combine them
Task::toFromAll()->concerned()->get();

Edit

To make the scopeConcerned() independent from your session (and not use Auth::id() inside it) declare it with a parameter.

public function scopeConcerned($query, $customerId){
    $query = $query->whereHas('organisations.organisateur', function($query) use($customerId) {
        $query->where('customers.id', $customerId);
    });

    return $query;
}

and use it like this

Task::concerned(Auth::id())->get();


Answered By - N69S

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.