codiaf
codiaf

Reputation: 639

Calling same eloquent statement in several controllers

I have an eloquent statement like this:

$constraint = function ($query) {
            $query->where('session', Session::getId());
};
$selectedImages = ImageSession::with(['folder' => $constraint])
                        ->whereHas('folder', $constraint)
                        ->where('type', 'single')
                        ->get();

Which I need to call in several controllers.

How is the best way to do it without putting this code every time?

Should I put this code in the Model? but how I put the ImageSession::with if it is inside the same model that has ImageSession class?

In the controller do I have to write...

$imageSession_table = new ImageSession;
$selectedImages = $imageSession_table->getSelectedImages();

Upvotes: 0

Views: 47

Answers (1)

Fabio Antunes
Fabio Antunes

Reputation: 22862

Well there are several solutions to this, but one rule that I have learned is whenever you are doing copy paste in the same file it means you need to create a function to encapsulate that code.

The same applies when you are copying and pasting the same code over classes/controllers it means you need to create a class that will have a method, that will encapsulate that code.

Now you could in fact change your model and this depends on your application and what kind of level of abstraction you have. Some people tend to leave the models as pure as possible and then use transformers, repositories, classes whatever you want to call it. So the flow of communication is something like this: Models -> (transformers, repositories, classes) -> Controllers or other classes

If that's the case just create a ImageSessionRepository and in there have your method to get the selected images:

<?php namespace Your\Namespace;

use ImageSession;
use Session;

class ImageSessionRepository
{
    protected $imageSession;

    public function __construct(ImageSession $imageSession)
    {
        $this->imageSession = $imageSession;
    }

    public function getSelectedImages($sessionId = false){
        if(!$sessionId){
            $sessionId = Session::getId()
        }

        $constraint = function ($query) use ($sessionId){
            $query->where('session', $sessionId);
        };
        $selectedImages = ImageSession::with(['folder' => $constraint])
                    ->whereHas('folder', $constraint)
                    ->where('type', 'single')
                    ->get();

        return $selectedImages;
    }
}

Then on your controller you just inject it:

<?php namespace APP\Http\Controllers;

use Your\Namespace\ImageSessionRepository;

class YourController extends Controller
{
    /**
     * @var ImageSessionRepository
     */
    protected $imageSessionRepository;

    public function __construct(ImageSessionRepository $imageSessionRepository)
    {
        $this->imageSessionRepository = $imageSessionRepository;
    }

    public function getImages()
    {
        $selectedImages = $this->imageSessionRepository->getSelectedImages();
        //or if you want to pass a Session id
        $selectedImages = $this->imageSessionRepository->getSelectedImages($sessionID = 1234);

        //return the selected images as json
        return response()->json($selectedImages);
     }
 }

Another option is adding that code directly into your Model, using scopes, more info here So on your ImageSession Model just add this function:

public function scopeSessionFolder($query, $session)
{
    $constraint = function ($constraintQuery) use ($sessionId){
        $query->where('session', $sessionId);
    };
    return $query->with(['folder' => $constraint])
                ->whereHas('folder', $constraint);
}

And on your controller just do this:

$selectedImages = ImageSession::sessionFolder(Session::getId())
                        ->where('type', 'single')
                        ->get();

Or you can include everything in your scope if that's your case

public function scopeSessionFolder($query, $session)
{
    $constraint = function ($constraintQuery) use ($sessionId){
        $query->where('session', $sessionId);
    };
    return $query->with(['folder' => $constraint])
                ->whereHas('folder', $constraint);
                ->where('type', 'single');
}

And then again on your controller you will have something like this:

$selectedImages = ImageSession::sessionFolder(Session::getId())
                            ->get();

Just a side note I haven't tested this code, so if you just copy and paste it it's possible that you find some errors.

Upvotes: 1

Related Questions