6

When creating an eloquent model:

Model::create(['prop1' => 1, 'prop2' => 2]);

the returned model will only have prop1 & prop2 as properties, what can I do to eager load all others properties that I haven't inserted in database because they are optional ?

EDIT: Why do I need this ? to rename my database fields:

database

CREATE TABLE `tblCustomer` (
    `pkCustomerID` INT(11) NOT NULL AUTO_INCREMENT,
    `baccount` VARCHAR(400) NULL DEFAULT NULL,
    `fldName` VARCHAR(400) NULL DEFAULT NULL,
    `fldNumRue` VARCHAR(10) NULL DEFAULT NULL,
    ....
    PRIMARY KEY (`pkCustomerID`)
);

customer model

<?php namespace App\Models;

/**
 * Class Customer
 * @package App\Models
 * @property int code
 * @property string name
 * @property string addressno
 */
class Customer extends Model
{
    protected $table = 'tblCustomer';
    protected $primaryKey = 'pkCustomerID';
    public $timestamps = false;

    /**
     * The model's attributes.
     * This is needed as all `visible fields` are mutators, so on insert
     * if a field is omitted, the mutator won't find it and raise an error.
     * @var array
     */
    protected $attributes = [
        'baccount'           => null,
        'fldName'            => null,
        'fldNumRue'          => null,
    ];

    /**
     * The accessors to append to the model's array form.
     * @var array
     */
    protected $appends = [
        'id',
        'code',
        'name',
        'addressno'
    ];

    public function __construct(array $attributes = [])
    {
        // show ONLY mutators
        $this->setVisible($this->appends);

        parent::__construct($attributes);
    }

    public function setAddressnoAttribute($value)
    {
        $this->attributes['fldNumRue'] = $value;
        return $this;
    }

    public function getAddressnoAttribute()
    {
        return $this->attributes['fldNumRue'];
    }
}

The problem is that when Laravel converts everything to JSON, he will parse all my mutators:

    public function getAddressnoAttribute()
    {
        return $this->attributes['fldNumRue'];
    }

and raise an error as $this->attributes['fldNumRue'] is not defined ErrorException: Undefined index... So I need a way to initialize all attributes with their default values.

kitensei
  • 2,510
  • 2
  • 42
  • 68

1 Answers1

8

You can call fresh() method on your model. It will reload the model from the database and return it. Keep in mind that it returns a reloaded object - it doesn't update existing one. You can also pass an array of relations that should be reloaded:

$model = $model->fresh($relations);

You could consider removing default values from the database and in your model. This way you won't need to reload model to get the defaults.

You can do it by overriding $attributes property in your model and seting defaults there:

class MyModel extends Model {
  protected $attributes = [
    'key' => 'default value'
  ];
}
jedrzej.kurylo
  • 39,591
  • 9
  • 98
  • 107
  • works great thank you ! But isn't there an automated way of retrieving the "fresh" version of an inserted model ? – kitensei Aug 21 '15 at 13:05
  • You can override method create in model (or base model) with this `return parent::create(...)->refresh()`, but this will be totally unefficient. – Jan.J Aug 21 '15 at 13:08
  • You can do as @Jan suggests, but think if you really need this. It will result in additional select query run for every insert – jedrzej.kurylo Aug 21 '15 at 13:10
  • There is another method here http://stackoverflow.com/questions/18747500/how-to-set-a-default-attribute-value-for-a-laravel-eloquent-model – Jan.J Aug 21 '15 at 13:10
  • I try to avoid database-defined defaults and set default values in create() signature. This way I don't need to refetch the objects – jedrzej.kurylo Aug 21 '15 at 13:10
  • Or you can just set defaults by setting them in $attributes field of your model – jedrzej.kurylo Aug 21 '15 at 13:13
  • I really like the *attributes* way, so I can avoid unnecessary SQL query on insert, the problem was that I rename all database fields, so *display* only the mutators, which raise an error if `$this->attributes['attrname']` is not initialized. – kitensei Aug 21 '15 at 13:19
  • I don't think I understand, could you post an example somewhere? – jedrzej.kurylo Aug 21 '15 at 13:26
  • I see. If your database field names are different than the ones in your model you need getter methods for them. Use database field names in $attributes - they need to be there as attributes array is later used to build an insert query and the field names must match. – jedrzej.kurylo Aug 21 '15 at 13:50