6

In several controllers i have to use the same method to show results as table with column sorting functionality:

 public function showSearchResults(Request $req){

        $query=Service::where('title', $req->search);

        // Columns sorting 
        if ($req->has('order')){
            $order= $req->order=='asc' ? 'asc' : 'desc';
            $order_inverse=$req->order=='asc' ? 'desc' : 'asc';
        } else {
            $order='desc';
            $order_inverse='asc';
        }

         ...


        $url=$req->url().'?'.http_build_query($req->except('sortby','order','page'));
        $results=$query->with('type')->paginate(15)->appends($req->all());


        return View::make('services.search_results')
                    ->with('results', $results)
                    ->with('url',$url)
                    ->with('sortby', $sortby)
                    ->with('order', $order)
                    ->with('order_inverse', $order_inverse);

    }

What is the best approach to avoid DRY in such case?

user947668
  • 2,548
  • 5
  • 36
  • 58
  • _“In several controllers i have to use the same method to show results as table with column sorting functionality. What is the best approach to avoid DRY in such case?”_ I’d first ask *why* you have controllers that are doing the same thing? Instead of skirting around the issue with a solution like traits, look at the *real* problem here: you have multiple controllers doing the same thing. – Martin Bean Apr 25 '16 at 13:50
  • Traits, as others have suggested, are the best way to do this. – heisian Apr 27 '16 at 18:49

4 Answers4

17

Sharing methods among Controllers with Traits

Step 1: Create a Trait

<?php // Code in app/Traits/MyTrait.php

namespace App\Traits;

trait MyTrait
{
    protected function showSearchResults(Request $request)
    {
        // Stuff
    }
}

Step 2: use the Trait in your Controller:

<?php // Code in app/Http/Controllers/MyController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Traits\MyTrait; // <-- you'll need this line...

class MyController extends Controller
{
    use MyTrait; // <-- ...and also this line.

    public function getIndex(Request $request)
    {
        // Now you can call your function with $this context
        $this->showSearchResults($request);
    }
}

Now you can use your Trait in any other controller in the same manner.

It is important to note that you don't need to include or require your Trait file anywhere, PSR-4 Autoloading takes care of file inclusion.

You can also use Custom Helper classes as others have mentioned but I would recommend against it if you only intend to share code among controllers. You can see how to create custom helper classes here.

Community
  • 1
  • 1
heisian
  • 6,127
  • 1
  • 17
  • 17
2

You can use traits (as ventaquil suggested) or you can create custom helpers file and add helpers there.

After that, you'll be able to use this helper from any class (controllers, models, custom classes, commands etc) like any other Laravel helper.

Alexey Mezenin
  • 158,981
  • 26
  • 290
  • 279
0

Use traits? More available here: http://php.net/manual/en/language.oop5.traits.php

ventaquil
  • 2,780
  • 3
  • 23
  • 48
0

You can create a helper file in your app directory. for eg. MethodHelper.php

In this file you can mention the method that you require using anywhere. For instance,

<?php namespace App;
class MethodHelper
{
 public static function reusableMethod()
    {
        //logic
    }
}

You can use this method anywhere, by using the namespace and calling the method. In the above eg. The namespace would be:

The method call function would look like:

MethodHelper::reusableMethod();

You can send parameters too based on your functional requirements. In your eg. you could have

public function showSearchResults(Request $req){
//
}

instead of reusableMethod(). Your call would be:

MethodHelper::showSearchResults($req);
Piya Desai
  • 130
  • 13