Jenssen
Jenssen

Reputation: 1871

Laravel ::__construct() must implement interface

I'm using Laravel 5.4 And I'm trying to inject a $order class into a trait that's going to implemented by a model. Like this:

class Forum extends Model
{
    use Orderable; 

The constructor of the trait looks like this:

trait Orderable
{
    public $orderInfo;

    public function __construct(OrderInterface $orderInfo)
    {
        $this->orderInfo = $orderInfo;
    }

My service provider looks like this:

public function register()
{
    $this->app->bind(OrderInterface::class, function () {
        return new Order(new OrderRepository());
    });

    $this->app->bind(OrderRepositoryInterface::class, function () {
        return new OrderRepository();
    });
}

The constructor of my Order class looks like this:

public function __construct(OrderRepositoryInterface $orderInfo)
{
    $this->orderInfo = $orderInfo;
}

But I receive the error:

Type error: Argument 1 passed to App\Forum::__construct() must implement interface Project\name\OrderInterface, array given, called in /home/vagrant/Code/Package/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 268

The OrderRepository class is implementing the OrderRepositoryInterface. The Order class is implementing the OrderInterface interface.

App\Forum is the model that uses the Orderable trait.

What could I be doing wrong here?

Upvotes: 1

Views: 2634

Answers (2)

Björn
Björn

Reputation: 5876

You are extending Model. This class already has a __construct that you need to use. This __construct expects array $attributes = [] as the first argument.

So in your __construct you also need to have this as the first argument and pass this to the parent class:

public function __construct(array $attributes = [], OrderRepositoryInterface $orderInfo)
{
    $this->orderInfo = $orderInfo;
    parent::__construct($attributes);
}

However you can work around using __construct in laravel using boot.

For example in a Model:

class Forum extends Model
{
    protected static function boot()
    {
        parent::boot();
        // Do something
    }
}

Or in a Trait:

trait Orderable
{
    public static function bootOrderableTrait()
    {
        static::created(function($item){
            // Do something
        });
    }
}

Upvotes: 1

Vitalii Kyrychenko
Vitalii Kyrychenko

Reputation: 316

In PHP it's not possible to have multiple constructors. If you will look to Model:

public function __construct(array $attributes = [])

it expect array. That's why I assume that somewhere in Model array passed to constructor instead of 'OrderInterface'.

Upvotes: 0

Related Questions