Ron Brouwers February 2016

Laravel Object Oriented

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');
    }
}

Answers


Helliax February 2016

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.


The Alpha February 2016

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.

Post Status

Asked in February 2016
Viewed 2,106 times
Voted 11
Answered 2 times

Search




Leave an answer