Search code examples
laravel-5interfacemodels

Implementing Interface on Model in Laravel


I have a Laravel 5 model Account which implements an Interface.

I have implemented all the methods of the Interface however when I run the code, Laravel complains that the Model does not implement the interface.

Error below

Account.php (Model)

<?php

namespace Abc\Accounts\Models;

use Abc\Accounts\Contracts\Accountlnterface;
use Illuminate\Database\Eloquent\Model;

class Account extends Model implements Accountlnterface {
....

In my Controller I am doing this

$account = Account::where('something', 'value')->first();

This returns the model just fine.

The problem lies when I pass it into another class controller

$result = new Transaction($account, 5.00);

Transaction file

public function __construct(Accountlnterface $account, float $value = 0.00) 
{
    $this->account = $account;

The transaction constructor is looking for the Interface however laravel is complaining that Account does not implement it.

Im not sure whats wrong with this code.

Error from Laravel

Type error: Argument 1 passed to Abc....\Transaction::__construct() must be an instance of Abc\Accounts\Components\Accountlnterface, instance of Tymr\Plugins\Accounts\Models\Account given.

Directly after the model is loaded I ran this code

        if($account instanceof AccountInterface)
            echo "working";
        else
            echo "fails";

and it certainly fails.


Solution

  • You need to register a service container binding in one of your service providers or better create a new service provider.

    It helps Laravel know the implementation to use for your interface.

    use Illuminate\Support\ServiceProvider;
    
    class ModelsServiceProvider extends ServiceProvider {
          public function register()
          {
             $this->app->bind(
                'Abc\Accounts\Contracts\Accountlnterface',
                'Abc\Accounts\Models\Account'
             );
          }
    }
    

    In app/config/app.php, register your service provider under the available providers.

    'providers' => [
        ...
        'ModelsServiceProvider',
    ]