Constructors on classes extending Eloquent
Asked Answered
F

4

19

I just started a new website and I wanted to make use of Eloquent. In the process of seeding my database, I noticed that I would get empty rows added if I had included any kind of constructor on the model that extends eloquent. For example, running this seeder:

<?php

class TeamTableSeeder extends Seeder {

    public function run()
    {
        DB::table('tm_team')->delete();

        Team::create(array(
            'city' => 'Minneapolis',
            'state' => 'MN',
            'country' => 'USA',
            'name' => 'Twins'
            )
        );

        Team::create(array(
            'city' => 'Detroit',
            'state' => 'MI',
            'country' => 'USA',
            'name' => 'Tigers'
            )
        );
    }

}

With this as my Team class:

<?php

class Team extends Eloquent {

    protected $table = 'tm_team';
    protected $primaryKey = 'team_id';

    public function Team(){
        // null
    }
}

Yields this:

team_id | city  | state | country   | name  | created_at            | updated_at            | deleted_at
1       |       |       |           |       | 2013-06-02 00:29:31   | 2013-06-02 00:29:31   | NULL
2       |       |       |           |       | 2013-06-02 00:29:31   | 2013-06-02 00:29:31   | NULL

Simply removing the constructor all together allows the seeder to work as expected. What exactly am I doing wrong with the constructor?

Forenamed answered 3/6, 2013 at 0:43 Comment(1)
Because Eloquent have it's own constructor and what you're doing unset all the action that eloquent need to work.Kunkel
H
30

You have to call parent::__construct to make things work here, if you look at the constructor of the Eloquent class:

public function __construct(array $attributes = array())
{
    if ( ! isset(static::$booted[get_class($this)]))
    {
        static::boot();

        static::$booted[get_class($this)] = true;
    }

    $this->fill($attributes);
}

The boot method is called and the booted property is set. I don't really know what this is doing but depending on your problem it seems relevant :P

Refactor your constructor to get the attributes array and put it to the parent constructor.

Update

Here is the needed code:

class MyModel extends Eloquent {
    public function __construct($attributes = array())  {
        parent::__construct($attributes); // Eloquent
        // Your construct code.
    }
}
Heelpiece answered 3/6, 2013 at 5:27 Comment(2)
A safe way to call the parent's constructor would be call_user_func_array(array('parent', '__construct'), func_get_args());Italianize
@Italianize But how would you define the new constructors expected arguments in this specific case?Secondrate
W
1

In laravel 3 you must put the second parameter '$exists' with default value "false".

class Model extends Eloquent {

    public function __construct($attr = array(), $exists = false) {
        parent::__construct($attr, $exists);
       //other sentences...
    }
}
Wellread answered 1/7, 2014 at 11:13 Comment(0)
S
0

You can use this generic method that allows you to pass a parameter too.

/**
* Overload model constructor.
*
* $value sets a Team's value (Optional)
*/
public function __construct($value = null, array $attributes = array())
{
     parent::__construct($attributes);
     $this->value = $value;
     // Do other staff...    
}
Spic answered 27/4, 2017 at 8:27 Comment(0)
H
0

I faced the same problem and I solved passing arguments with the constructor.

class MyModel extends Model
{
    public function __construct(array $attributes = []) {
        parent::__construct($attributes);

        // ...
    }
 }

Then call like regular class,

$result = (new MyModel($request->all()))->create($request->all());
Hypervitaminosis answered 21/2, 2022 at 15:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.