エンジニアのひよこ_level10

毎日更新してた人。たまに記事書きます。

【Laravel】Eloquentのcreateとfillの違いとは【336日目】

■注意

コードは5.2のコードです。ですが、そんなにバージョン上がっても変わってないはずです。

■結論

基本的にcreateで大丈夫

■違い

1.createはどうせfill通るので、fillableやguardedの部分は両方使う

2.createは、静的メソッドで、以下までしてくれる

1. インスタンス化
2. 値の確認・保存
3. インスタンスを返す

3.fillは、インスタンスを用意して、fillして、save()を呼び出すの3工程が必要

■使い方の違い

create

$user = User::create(['name' => 'Uiro']);

fill

$user = new User();

$user->fill(['name' => 'Uiro']);

$user->save();

■元コード+私のコメント

createがfillを動かしてるのは以下のコメント参照

   /**
    * Save a new model and return the instance.
    *
    * @param array $attributes
    * @return static
    */
    public static function create(array $attributes = [])
      {
        $model = new static($attributes); //ここで、呼び出し元をインスタンス化してる。なので下の__constructを通る

        $model->save();

        return $model;
      }

    /**
     * Create a new Eloquent model instance.
     *
     * @param  array  $attributes
     * @return void
     */
    public function __construct(array $attributes = [])
    {
        $this->bootIfNotBooted();

        $this->syncOriginal();

        $this->fill($attributes); //fillをしている
    }

fillはsaveまでしてないので、saveを書かないといけない。

また、静的メソッドではないので、インスタンス化してください。

/**
     * Fill the model with an array of attributes.
     *
     * @param  array  $attributes
     * @return $this
     *
     * @throws \Illuminate\Database\Eloquent\MassAssignmentException
     */
    public function fill(array $attributes)
    {
        $totallyGuarded = $this->totallyGuarded();

        foreach ($this->fillableFromArray($attributes) as $key => $value) {
            $key = $this->removeTableFromKey($key);

            if ($this->isFillable($key)) {
                $this->setAttribute($key, $value);
            } elseif ($totallyGuarded) {
                throw new MassAssignmentException(sprintf(
                    'Add [%s] to fillable property to allow mass assignment on [%s].',
                    $key, get_class($this)
                ));
            }
        }

        return $this;
    }

■使い分け

1.インスタンスが既にある
2.saveを後回しにしたい

ならfillを使って、基本的にはcreateで良いと思います。