Tim Lewis
Tim Lewis

Reputation: 29258

Laravel - Model::create() works, but is missing attributes

So, I have the following Models:

class Recursive extends Model {
  public function __construct() {
    parent::__construct();
  }
  // ...
}

class Place extends Recursive {
   protected $table = 'places';
   protected $fillable = ['name', 'parent_id'];
   // ...
}

The following code is used to create a new Place:

$place = Place::create([
  'name' = 'Second',
  'parent_id' => 1
]);

This results in the following record in the database:

| Actual                    | Expected                  |
---------------------------------------------------------
| id | name     | parent_id | id | name     | parent_id | 
| 1  | 'Top'    | NULL      | 1  | 'Top'    | NULL      |
| 2  | NULL     | NULL      | 2  | 'Second' | 1         |

As you can see, the only value being set is the Auto-incrementing id column. The 2 columns I'm trying to create are in the fillable array, and the model is created, but it's not associated correctly.

Has anyone come across this issue before? I know I can use another method, such as

$place = new Place();
$place->name = 'Second';
$place->parent_id = 1;
$place->save();

But this isn't the only spot I'm using this code, and I'd prefer to not lose functionality like this.

Edit: Enabling the query log shows the following for the create() call:

array (
  'query' => 'insert into `places` () values ()',
  'bindings' => 
  array (
  ),
  'time' => 1.26,
),

Further edit: Enable MySQL log has the same output as above. Following Miken32's suggestion of reverting the extends to Model works as expected:

array (
  'query' => 'insert into `places` (`name`, `parent_id`) values (?, ?)',
  'bindings' => 
  array (
    0 => 'Second',
    1 => '1'
  ),
  'time' => 1.21,
),

Upvotes: 3

Views: 2781

Answers (1)

miken32
miken32

Reputation: 42695

Checking the Illuminate\Database\Eloquent\Model class, the constructor looks like this:

public function __construct(array $attributes = [])
{
    $this->bootIfNotBooted();
    $this->initializeTraits();
    $this->syncOriginal();
    $this->fill($attributes);
}

However, you overrode this in your Recursive class:

public function __construct()
{
    parent::__construct();
}

The attributes were not being passed to the constructor, so it was not able to successfully build the query. You could remove the constructor since it's not doing anything, or use this instead:

public function __construct(array $attributes = [])
{
    parent::__construct($attributes);
}

Upvotes: 5

Related Questions