LoginSignup
14

More than 5 years have passed since last update.

Eloquentのモデル生成法比較:newとcreate

Posted at

Laravelで入っているEloquent ORMの、本当に微妙な使い方の話です。

Eloquentのモデルからエンティティオブジェクトを生成するには、2つ方法があります。

$entity1 = new Model();
$entity2 = Model::create( array() );

この2つの方法の違いは、createを使うと、すぐにDBに保存されます。
まぁ殆ど差がないわけです。が、リレーションを使う場合にちょっと
createのほうが使いやすいかもしれません。

具体的なケースとして、簡単なブログとコメントの場合を考えます。

class Blog extends Eloquent {
  public comments() {
    return $this->hasMany('Comment');
  }
}
class Comment extends Eloquent {
  public blogs() {
    return $this->BelongsTo('Blog');
  }
}

よくあるブログのサンプルです。
で、新しいブログとコメントを一度に作って保存しようとすると…

$blog = new Blog();
$comment = new Comment();
$blog->comment()->save($comment); // 例外発生!

原因は…$blogはDBに保存される前なので、キー(ID)が設定されてない状態になっている。
にもかかわらずリレーションで使おうとすると例外が発生する(なのだと思われます)。

で、createを使ってエンティティを生成していると、例外が発生しません。

$blog = Blog::create(array());
$comment = Comment::create(array());
$blog->comment()->save($comment); // 問題なし!

ひとまずエンティティはcreateメソッドを使って生成しようと
思ってます。

問題点は?

まだEloquentを使い始めたばかりなので、
よく知りませんが、思いつく問題点としては…

新しく生成したのかDBから読み込んだエンティティなのか、
判定する方法としては、

  • getKey()でキーが存在するかどうか、
  • existsフィールドがfalse、

がありますが、どちらも使えません。
少なくともオブジェクトを調べただけでは判別できなくなります(多分)。

それと、

エンティティを生成した後に問題が発生して、処理をキャンセルする場合を考えると、トランザクションの中で走らせる必要はあると思います。が、リレーションを設定すると、(BelongsToのassociateを除いて)設定した時点でDBに保存されるので、どちらにしてもトランザクション使わないと問題あるので同じな気はします。

などでしょうか。

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
14