简体   繁体   中英

How to fill a custom object via the repository pattern and Laravel's Eloquent

Okay, so here's the deal. I'm working with a custom CMS, and I'd like for the code to be as optimized as possible. I've been reading/watching tuts/etc. like crazy about the repository pattern in general as well as specifically using it with Laravel's Eloquent. There are probably some really dumb questions/thoughts in here, but bear with me. :-) Sometimes there's no easy way to ask about terminology/best practices without looking silly.

As with many things, there are million ways I could "make it work"; my dilemma is essentially a matter of "best practice."

General Scenario/Question

Let's assume I am trying to get a Page for my CMS from the database. From what I can understand the typical way to set up the repository pattern with Eloquent is to have the following files:

  • Page.php -- the Eloquent Model
  • PageRepositoryInterface.php -- the "contract" for what should be in Page repo's
  • EloquentPageRepository.php -- the Page repository that can grab data via Eloquent

Easy enough. So I might use it this way. Assuming I have a getPageById method in EloquentPageRepository.php , I could just do something like this from my controller:

$page = $this->repo->getPageById();

Now my question arises: what type of data should getPageById() return? Some people recommend setting it up to return an Eloquent collection. Others say just a plain array or generic object.

Ideally I feel like my scenario would best lend itself to having EloquentPageRepository grab the data from Eloquent and actually return an instance of a custom Page class that I have. For example, something along the lines of this:

<?php  namespace Acme\Repositories\EloquentPageRepository;

use Acme\...\PageObject as PageObject; // Better name than PageObject?

//...

class EloquentPageRepository implements PageRepositoryInterface {

    // Omitting constructor, etc.

    public function getPageById($id)
    {
        // Grab the row via Eloquent (obviously not stored in Page:: at
        // this point. I'm just using it here for clarity and time's sake.
        $page = Page::find($id);

        // Now we have an Eloquent collection stored in $page, but I'd
        // like to return the data inside an instance of my custom class.
        $pageObj = new PageObject($page->title, $page->body);

        return $pageObj;
    }
}

To me, this seems good because it gives a consistent delivery format from repo to repo. It also allows me to perform some constructor logic on my pageObject. Finally, it allows me to have some custom methods on the PageObject (that are repository-agnostic).

It's similar to a collection, but I don't think it's exactly that. It's basically just an instance of a class that I'm immediately populating with my database info.

My questions, listed:

  1. Is it considered bad practice to use a repo to stuff eloquent data into a specific object and return it?
  2. I don't want to call my class "PageObject," because that's just lame. I'd way rather call it something like "PageCollection," except for the fact that it's not actually a collection. Is there actually a name for the way that I'm using this class? It's not a collection, it's a ...? I have no idea about this, I'm just searching for any input you have.
  1. It whole depends on what you expect from the repository pattern. Are you using the repository pattern because in the future you're going to swith of data layer and needs a new repository. If you're using Eloquent as long as your cms live then you can return an eloquent object. If you want it very flexible then make a new page object(PageComposer as mentioned in the comments). This is one of the strengts of the repository pattern so I suggest you make a PageComposer class which you instantiate and return by the repository.
  2. Normally you can call it Page because its a page and it ships some information of a page. But that name you've already give to the Eloquent model. You can consider changing the eloquent models name and call your return object Page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM