Skip to content

Instantly share code, notes, and snippets.

@JeffreyWay
Last active February 25, 2019 01:36
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JeffreyWay/5438984 to your computer and use it in GitHub Desktop.
Save JeffreyWay/5438984 to your computer and use it in GitHub Desktop.
Laravel challenge / poll for book.

Challenge: you need a flexible (swap in other repository implementations) way to display some kind of resource. Let's say, Posts. What does your folder structure look like?

Requirements:

  • Repository implements an interface
  • Must show at least one implementation of the interface (Eloquent version is fine)
  • The interface is injected into your PostsController.
  • Show where you register your IoC bindings
  • Show folder structure. Where are interfaces/repositories stored?
@ccovey
Copy link

ccovey commented Apr 22, 2013

@fideloper I said abstract :)

I was thinking more that you would have an interface with your contract and an abstract that would have common methods and implementations per repository. Not as a way to implement a contract just as a way to keep things DRY

@fideloper
Copy link

We're all in agreement then :D

@dannewns
Copy link

hey all just wondering if you might be able to help me out, i've just read through each example and its got me thinking that im now doing things wrong as i dont write my code in this way at all and that I should really start to, for the reasons mentioned above.

My main question is that within the post interface will I have to name all the methods that are default with Eloquent such as find or all() or even the type of whereField() methods? or can i just use them as you did with

$this->post::whereOrderNo($order_no)

sorry if I sound really stupid here, its just i've never really written code like the above and since starting using L4 its really made me think about how im doing things and how I can write better code which im very enjoyable!

thanks

Dan

@JonoB
Copy link

JonoB commented Apr 23, 2013

Dan, nothing wrong per se with the way that you are currently doing it. This is just better abstraction and allows for better testing. You are not looking to replicate eloquent - its just a way of moving the methods from your controller to the repo. Each method in the repo will contain an eloquent (or query builder) call - what's actually inside that call is totally up to you. I typically have something like the following for a resource type repo (removed some internal workings and been a bit more explicit than usual, but this will suffice):

class ContactRepository implements ContactRepositoryInterface
{
    public function all()
    {
        return Contact::with('type')->orderBy('name')->get();
    }

    public function find($id)
    {
        return Contact::findOrFail($id);
    }

    public function store($data = null)
    {
        $data = $data ?: Input::all();
        $contact = new Contact($data);

        return $contact->save();;
    }

    public function update($id, $data = null)
    {
        $data = $data ?: Input::all();
        $contact = $this->find($id);
        $contact->fill($data);

        return $contact->save();
    }
}

@dannewns
Copy link

@JonoB thanks for that it clarifies a lot of stuff for me. Id really like to start writing things that will be better for testing etc so seeing this kind of challenge put up by @JeffreyWay has really made me think about it all. Great work all and thanks again.

@dannewns
Copy link

Could this setup also be used for an email implementation for instance I know i can use Mail::send() whenever i want to send mail but when im testing using real data i would like any emails sent out to go to me as the developer and then when going live it to default to going to the correct user.

I could keep changing the to address each time and remember to set them back for go live but that seems like a bit of a hack, is there a way i could use an interface like above to create my own send method which then inside of that does the checking if im in dev mode and then uses a config to address if not it uses the to address passed to it.

Would the folder structure be along the lines of

# Inside of app/lib
Appname
    Email
       EmailInterface.php
       Email.php
    EmailServiceProvider.php

or does that look odd, or should i just be extending the Email class in the first place, sorry if im going off topic here.

@JonoB
Copy link

JonoB commented Apr 29, 2013

I have a question on this: how much do you abstract away from your controllers? For example, lets say that we are creating a user. Along with saving the user, we also want to automatically assign the user's group and fire off an email to the user. Do you:

  • Place all of the above in your UserRepository.store() method
  • Only save the user in Repository.store(). Return bool to controller - if true then save group (using UserGroup Repository) and then fire off the email in the controller
  • Something else?

@williamcolbert
Copy link

Love this challenge actually helping me with getting into abstraction.

But one question I have is , I see alot of people implementing for instance in this version posted, the Post class extending eloquent shouldn't this Post class be a entity that just defines what the Post is made up of and function to act on the entity and not extending Eloquent ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment