PHP User
PHP User

Reputation: 2422

Laravel: How to implement Repository Design Pattern with only one repository?

I've checked many repository design pattern tutorials like

https://asperbrothers.com/blog/implement-repository-pattern-in-laravel/ https://www.larashout.com/how-to-use-repository-pattern-in-laravel https://laravelarticle.com/repository-design-pattern-in-laravel https://shishirthedev.medium.com/repository-design-pattern-in-laravel-application-f474798f53ec

But all use multiple repositories with all methods repeated for each model here's an example

class PostRepository implements PostRepositoryInterface
{
  public function get($post_id)
  {
    return Post::find($post_id);
  }

  public function all()
  {
    return Post::all();
  }
} 

interface PostRepositoryInterface
{
  public function get($post_id);

  public function all();
}

class PostController extends Controller
{

  protected $post;

  public function __construct(PostRepositoryInterface $post)
  {
    $this->post = $post;
  }

  public function index()
  {
    $data = [
        'posts' => $this->post->all()
    ];
    return $data;
  }
}

In ReposiroryServiceProvider:

$this->app->bind(
    'App\Repositories\PostRepositoryInterface',
    'App\Repositories\PostRepository'
);

So now I have UserRepository, PostRepository, CommentRepository .... etc I will have to add the same methods of get, add, .... in all repositories and just change the model name from Post to User .... etc

How can I unify these methods in one file and just pass the model name and use it like this $this->model->all() instead of repeating them in every repository file I create?

Upvotes: 0

Views: 512

Answers (1)

Maksim
Maksim

Reputation: 2957

You need Abstract Class AbstractRepository, something like this.

Btw, maybe you don't need repository pattern, in Laravel it is not best practice.

abstract class AbstractRepository
{
     private $model = null;
     //Model::class
     abstract public function model(): string
     protected function query()
     {
         if(!$this->model){
           $this->model = app($this->model());
         }
         return $this->model->newQuery()
     }
     public function all()
     {
        return $this->query()->all();
     }
}

Upvotes: 1

Related Questions