0

I am somewhat new to OOP, although I know about interfaces and abstract classes a bit. I have a lot of resource controllers that are somewhat similar in the bigger scheme of things, they all look like the example below, the only main difference is the index and what I pass to the index view.

What I simply need to know is, can I OO things up a bit with my resource controllers? For example, create one "main" resource controller in which I simply pass the correct instances using an interface for example? I tried playing around with this but I got an error that the interface wasn't instantiable, so I had to bind it. But that means I could only bind an interface to a specific controller.

Any advice, tips and pointers will help me out :)

class NotesController extends Controller
{
    public function index()
    {
        $notes = Note::all();

        return view('notes.index', compact('notes'));
    }

    public function create()
    {
        return view('notes.create');
    }

    public function show(Note $note)
    {
        return view('notes.show', compact('note'));
    }

    public function edit(Note $note)
    {
        return view('notes.edit', compact('note'));
    }

    public function store(Request $request, User $user)
    {
        $user->getNotes()->create($request->all());

        flash()->success('The note has been stored in the database.', 'Note created.');

        return Redirect::route('notes.index');
    }

    public function update(Note $note, Request $request)
    {
        $note->update($request->all());

        flash()->success('The note has been successfully edited.', 'Note edited.');

        return Redirect::route('notes.index');
    }

    public function delete($slug)
    {
        Note::where('slug', '=', $slug)->delete();

        return Redirect::to('notes');
    }
}
Hardist
  • 2,098
  • 11
  • 49
  • 85

2 Answers2

1

Note: Totally my opinion!

I would keep them how you have them. It makes them easier to read and understand later. Also will save you time when you need to update one to do something different from the rest. We tried this in a project I worked on and while granted it wasn't the best implementation, it is still a pain point to this day.

Up to you though. I'm sure people have done that in a way that they love and works great. Just hasn't been the case in my experience. I doubt anyone would look at your code though and criticize you for not doing it.

Dylan Buth
  • 1,648
  • 5
  • 35
  • 57
  • Yeah it's just for my personal project and I am just learning, but I intend to use this project for myself so :) Was just wondering since I have 15 controllers already which basically do the same things, and there will be a bunch more. But hey, if this is a good way to go about it, then it's okay. – Hardist Feb 08 '16 at 12:34
  • 1
    If you are using all the resource controllers then I don't think that's a bad way to do it. – Dylan Buth Feb 08 '16 at 12:44
1

In Case you need to bind different Model instanses then you may use Contextual Binding, for example, put the following code in AppServiceProvider's register() method:

$this->app->when('App\Http\Controllers\MainController')
        ->needs('Illuminate\Database\Eloquent\Model')
        ->give(function () {
            $path = $this->app->request->path();
            $resource = trim($path, '/');
            if($pos = strpos($path, '/')) {
                $resource = substr($path, 0, $pos);
            }
            $modelName = studly_case(str_singular($resource));
            return app('App\\'.$modelName); // return the appropriate model

    });

In your controller, use a __construct method to inject the model like this:

// Put the following at top of the class: use Illuminate\Database\Eloquent\Model;

public function __construct(Model $model)
{
    $this->model = $model;
}

Then you may use something like this:

public function index()
{
    // Extract this code in a separate method
    $array = explode('\\', get_class($this->model));
    $view = strtolower(end($array));

    // Load the result
    $result = $this->model->all();
    return view($view.'.index', compact('result'));
}

Hope you got the idea so implement the rest of the methods.

The Alpha
  • 143,660
  • 29
  • 287
  • 307