Support the ongoing development of Laravel.io →
Database Eloquent Architecture

Hey guys. I want to start working with repositories because right now I handle all the data from the database on my eloquent models. My biggest concern with it is that I don't know well how to manage the relationships.

This is my idea:

class PostEloquentRepository extends PostRepositoryInteface
{
    protected $post;
    protected $category;

    public function __construct(Post $post, CategoryRepositoryInterface $category)
    {
        $this->post = $post;
        $this->category = $category;
    }

    public function create($title, $content, $category)
    {
        $category = $this->category->byId($category);

        $post = $this->post->create([
            'title' => $title,
            'content' => $content,
            'category' => $category->id,
        ]);

        return $post->toArray();
    }
}

The id is not taken from the Category model but from the category repository. The problem I have with this is that it seems like models are isolated, and if I want to get all the post of a category, instead of just do Category::whereID(5)->with('posts'); as I do now, I will have to do something like:

$category = CategoryRepo::byId('5); $category->posts = PostRepo::byCategory($category->id);

So, I kind of lose the simplicity I have with Eloquent.

What do you think?

Last updated 3 years ago.
0

Where and how do you use PostEloquentRepository? Do you call 'create' from your controller?

It would be nice if you can post your client code.

Last updated 3 years ago.
0

I guess I just reply it based on your code.

You probably need a service class.

$category = $this->category->byId($category); is problematic because you might be finding a record that might not exists, meaning that you need to validate it in your repository. IMO, validating should not be done in your repository. When you call 'create', that means that you've already validated all the data and you just want to save the data to a persistence storage.

The following classes should give you an idea..I hope.

class PostService
{

	private $postRepository;
	private $categoryRepository;

	public function __construct(PostRepositoryInterface $postRepository, CategoryRepositoryInterface $categoryRepository)
	{
		$this->postRepository = $postRepository;
		$this->categoryRepository = $categoryRepository;
	}

	public function create($title, $content, $category)
	{
		$category = $this->category->byId($category);

		if (!$category) {
			// do something
		}

		return $this->postRepository->create([
			'title' => $title,
			'content' => $content,
			'category' => $category->id
		]);

	}

}

class PostEloquentRepository implement PostRepositoryInteface
{
    protected $post;

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

    public function create(array $data)
    {
        $post = $this->post->create($data);
        return $post->toArray();
    }
}


class PostController 
{	

	private $postService;

	public function __construct(PostService $postService)
	{
		$this->postService = $postService;
	}

	public function create()
	{
		// use post service here
	}

}
Last updated 3 years ago.
0

Your repository shouldn't extend an interface, it should implement an interface. Big difference.

Injecting the model is the right idea though. You want to start off like this:

class PostRepository implements PostRepositoryInterface {

}

Laracasts has a lot of good stuff on using dependency injection. Check it out.

Last updated 3 years ago.
0

@AnthonyVipond as much as I love laracasts (I'm a yearly member), recommending to a premium service without even trying to give the OP your opinions and answers is just wrong IMO. 5 lines of post and a premium service recommendation?

Nice catch on the extending interface. I didn't even notice it lol

Last updated 3 years ago.
0

You can just inject the category model in as well instead of injecting the category repository. I don't see any other methods in your code specifically calling something from the category repository.

Then you could do:

$this->category->with('posts')->where('id', 5)->get();

as you desired.

I don't see what's wrong with me recommending Laracasts either. I see someone who halfway understands the repository pattern and could go to fully understanding it after watching the architecture videos there :) Should recommend Chris Fidao's book as well while I'm at it.

Last updated 3 years ago.
0

@AnthonyVipond // I don't see either as long as you provide OP something. I mean..this is larval forum, not a place where you just recommend a premium service without providing something to discuss. If we can do that, why don't we just subscribe to Laracast without asking/discussing on this forum?

Last updated 3 years ago.
0

I'd do what moon0326 suggested - create a service class where you inject both repositories and do the necessary checking. Then, the create function on the post repository can accept a category instance as an optional argument, so it can associate the post with the category if necessary.

Last updated 3 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

daninoz daninoz Joined 5 Jan 2014

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2025 Laravel.io - All rights reserved.