user3489502
user3489502

Reputation: 3611

Laravel method that can be used by multiple controllers and commands. Where should it be?

I'd like to define a "global" method that can be used by multiple controllers and commands. Where should it be placed in Laravel 5.4?

Let's say I have the following controller. How would I call the "global" method instead, and where would that "global" method be located exactly?

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;

use App\Flight;

class FlightsController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Index
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $flights = Flight::where('active', 1)
               ->orderBy('name', 'desc')
               ->take(10)
               ->get();

        foreach ($flights as $flight) {
            if ( $flight->price == 0 )
            {
                $output = "some value";
            }
            else
            {
                $output = "some other value";
            }
        }

        return view('flights.index')
                ->with(['output'   => $output])
                ;
    }
}

Upvotes: 6

Views: 2081

Answers (4)

Alex
Alex

Reputation: 4811

I think that service is the best option to store the functionality which is shared between controllers and commands. You can access them using Service Container (https://laravel.com/docs/5.5/container).

Upvotes: 0

Moppo
Moppo

Reputation: 19275

When you want a method that fetches many models, and you want to use it in many places, put it in a Repository:

class FlightRepository
{
    public function getLastTenFlights()
    {
        return Flight::where('active', 1)
           ->orderBy('name', 'desc')
           ->take(10)
           ->get();
    }
}

For example from your controller:

public function index( FlightRepository $repo )
{
    $flights = $repo->getLastTenFlights();

    //if you want you can put this additional login in the method too... 
    foreach ($flights as $flight) {
        if ( $flight->price == 0 )
        {
            $output = "some value";
        }
        else
        {
            $output = "some other value";
        }
    }

    return view('flights.index')
            ->with(['output'   => $output])
            ;
}

Upvotes: 6

Samsquanch
Samsquanch

Reputation: 9146

I personally prefer query scopes to repositories, so I would do something like this:

class Flight extends Model
{

    // model setup

    /**
     * Scope query to get last 10 flights.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeLastTen($query)
    {
        return $query->where('active', 1)->orderBy('name', 'desc')->take(10);
    }

    // rest of model
}

And you can use it similarly to how you're currently using it, only it's more readable:

$flights = Flight::lastTen()->get();

This also has the advantage of being able to chain other queries off of it. Say, for example, you wanted the last ten American Airlines flights, you could do:

$flights = Flight::lastTen()->where('airline', 'American')->get();
// equivalent to
// $flights = Flight::where('airline', 'American')->lastTen()->get();

Upvotes: 0

user8574331
user8574331

Reputation:

You can create a Object and call the object when you want.

See example:

FlighRepository = new FlighRepository;

FlighRepository->index();

Upvotes: 0

Related Questions