Search code examples
laravelrepositorymodels

Repository pattern (Laravel) switching beetwen models


I'm writing an app in Laravel using the repository pattern. The main idea is to write one repository that will handle 2 models based on route parameters.

So my routes.php looks like this:

Routes.PHP

<?php $api = app('Dingo\Api\Routing\Router');


$api->version('v1', function ($api)
{
    $api->post('create/{type}', ['uses' => 'Beyondi\Account\Http\Controllers\AccountController@insert']);

});

AccountController.php

class AccountController extends Controller
{

    /**
     * Generate JSON Web Token.
     */
    protected $account;

    public function __construct(TypeRepositoryInterface $user)
    {
        $this->account = $user;
    }


    public function insert(AccountRequest $request)
    {
        if($this->account->create($request->input()))
        {
            return $this->response->array("User inserted")->setStatusCode(200);
        }else
        {
            return $this->response->array("Error, user not inserted")->setStatusCode(500);
        }
    }

AccountRequest.php

class AccountRequest extends Request
{
    public function __construct(FormRequest $request)
    {

        if ($request->route('type')=='consumer')
        {
            $rules=[
                'looking_for' => 'required|in:male,female,trans',
                'photo' => 'required',
                'newsletter' => 'boolean|required'
            ];
            $this->rules($rules);
        }else
        {
            $rules=[
                'type' => 'required|in:private,agency',
                'sexuality' => 'required|in:hetero,bi,homo',
                'height' => 'required|numeric'
            ];
            $this->rules($rules);

        }
    }

    public function rules($rules)
    {

        return [$rules];
    }

    public function authorize()
            {
                return true;
            }
        }

TypeRepositoryInterface.php

interface TypeRepositoryInterface
{
    public function create(array $data);

    public function update($id, array $data);

    public function delete($id);

    public function getAll(array $columns = ['*']);

    public function findById($id, $columns = ['*']);

}

AbstractRepository.php

abstract class AbstractRepository implements AbstractRepositoryInterface
{
    protected $model;

    /**
     * Create new repository interface
     *
     * @param Model $model
     */
    public function __construct(Model $model)
    {
        $this->model = $model;
    }

    /**
     * Get new instance of model
     *
     * @param array $attributes
     * @return static
     */
    public function getNew(array $attributes = [])
    {
        return $this->model->newInstance($attributes);
    }

    /**
     * Insert new data in database
     *
     * @param array $data
     * @return static
     */
    public function create(array $data)
    {
        return $this->model->create($data);
    }

    /**
     * Update data in database
     *
     * @param $id
     * @param array $data
     * @return mixed
     */
    public function update($id, array $data)
    {
        return $this->model->whereId($id)->update($data);
    }

    /**
     * Delete data from database
     *
     * @param $id
     * @return bool|null
     * @throws \Exception
     */
    public function delete($id)
    {
        return $this->model->delete($id);
    }

    /**
     * Get all data from database
     *
     * @param array $columns
     * @return \Illuminate\Database\Eloquent\Collection|static[]
     */
    public function getAll(array $columns = ['*'])
    {
        return $this->model->all($columns);
    }

    /**
     * Find data by id
     *
     * @param $id
     * @param array $columns
     * @return \Illuminate\Support\Collection|null|static
     */
    public function findById($id, $columns = ['*'])
    {
        return $this->model->find($id, $columns);
    }


}

TypeRepository.php

class TypeRepository extends AbstractRepository implements TypeRepositoryInterface
{
    protected $model;

    /**
     * Create new repository interface
     *
     * @param Model $model
     */
    public function __construct(ProviderModel $providerModel,ConsumerModel $consumerModel,Request $request, $type)
    {
        if ($request->route('type')=='consumer')
        {
            $this->model = $consumerModel;
        }else
        {
            $this->model = $providerModel;
        }

    }


}

As you can see I am trying to switch between 2 models in my TypeRepository based on route {type} parameter. However I get

Unresolvable dependency resolving [Parameter #3 [ <required> $type ]] in class Account\\Repositories\\Type\\Eloquent\\TypeRepository

error. What am I missing? How to do it correctly?


Solution

  • You are not type-hinting the $type parameter of the TypeRepository constructor so the service container can't instantiate it.

    I would suggest removing the $type parameter and using this instead:

    $type = $request->input('type');
    

    inside your constructor.