1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravelのcreate()、save()、insert()の違い

Posted at

各メソッドの挙動の違い

DB保存の方法はいくつかあるが、どういう違いがあるかを把握せずに使っていたため、主に使うcreate()save()insert()の違いをまとめていく。

create()

指定された属性を持つ新しいモデルインスタンスを作成し、データベースに保存してからそのインスタンスを返す。

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

vendorの中を見にいくと以下のようなコードが書かれている。

vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php
/*
 * Save a new model and return the instance.
 *
 * @param  array  $attributes
 * @return \Illuminate\Database\Eloquent\Model|$this
 */
public function create(array $attributes = [])
{
    return tap($this->newModelInstance($attributes), function ($instance) {
        $instance->save();
    });
}

save()

モデルのインスタンスをデータベースに保存する。create()と異なり、保存後インスタンスは返さず、保存が成功したかどうかを示すブール値を返す。

また、モデルが既にデータベースに存在する場合(モデルがデータベースから取得された場合や、新しいレコードがデータベースに挿入された後等)は更新を行い、存在しない場合は新規保存を行う。

$user = new User();
$user->name = $request->name;
$user->save();

vendorの中を見にいくと以下のようなコードが書かれている。

vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php
/*
 * Save the model to the database.
 *
 * @param  array  $options
 * @return bool
 */
public function save(array $options = [])
{
    $query = $this->newModelQuery();

    // If the "saving" event returns false we'll bail out of the save and return
    // false, indicating that the save failed. This provides a chance for any
    // listeners to cancel save operations if validations fail or whatever.
    if ($this->fireModelEvent('saving') === false) {
        return false;
    }

    // If the model already exists in the database we can just update our record
    // that is already in this database using the current IDs in this "where"
    // clause to only update this model. Otherwise, we'll just insert them.
    if ($this->exists) {
        $saved = $this->isDirty() ?
                    $this->performUpdate($query) : true;
    }

    // If the model is brand new, we'll insert it into our database and set the
    // ID attribute on the model to the value of the newly inserted row's ID
    // which is typically an auto-increment value managed by the database.
    else {
        $saved = $this->performInsert($query);

        if (! $this->getConnectionName() &&
            $connection = $query->getConnection()) {
            $this->setConnection($connection->getName());
        }
    }

    // If the model is successfully saved, we need to do a few more things once
    // that is done. We will call the "saved" method here to run any actions
    // we need to happen after a model gets successfully saved right here.
    if ($saved) {
        $this->finishSave($options);
    }

    return $saved;
}

insert()

複数のレコードを一度に保存する。直接SQLのINSERT文を実行するため、タイムスタンプの更新等は行わない。また、fillableのチェックが行われないため、複数代入による脆弱性が発生する可能性もある。

User::insert([['name' => 'hoge']]);

vendorの中を見にいくと以下のようなコードが書かれている。

vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php
/*
 * Save a new model and return the instance.
 *
 * @param  array  $attributes
 * @return \Illuminate\Database\Eloquent\Model|$this
 */
public function create(array $attributes = [])
{
    return tap($this->newModelInstance($attributes), function ($instance) {
        $instance->save();
    });
}

まとめ

  • create():新しいモデルインスタンスを作成、データベースに保存してそのインスタンスを返す
  • save():既存のモデルインスタンスをデータベースに保存する。新しいインスタンスを保存することも可能
  • insert():複数のレコードを一度に挿入する。fillable属性のチェックがされないので使い時に注意
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?