9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Laravel] $fillableと$guarded/モデルの新規作成と更新まとめ

Last updated at Posted at 2021-06-09

はじめに

モデルの新規作成や更新を行う方法がいくつかあるため(さまざまな記事で見かけます)、この際にまとめ、「どれがベストなのか」自分なりの結論を出したいと思います。

検証環境

  • macOS Catalina ver 10.15.7
  • Docker ver 20.10.5
  • docker-compose ver 1.29.0
  • Laravel ver 7.30.4
  • MySQL ver 8.20.3

$fillableと$guarded

$fillableのメリットとデメリット

メリット

  • 指定したカラムのみ値の代入を許可する。

デメリット

  • カラムが増えるたびにその都度、付け加えなければならない。
    • カラム数が多いテーブルは特に大変。

$guardedのメリットとデメリット

メリット

  • 値の代入を禁止するカラムだけを指定すれば良いので、カラムが増えても、その都度$guardedに加えなくて良い($guardedとして定義したいカラムが増えれば、都度付け加えなければなりませんが...)。

デメリット

  • 指定したカラム以外の値の代入が行われるので、$guardedのみ見た場合、他のどのカラムの操作が許可されているか把握しづらい。
    • 言い換えるならば、「$guardedに定義されていないから、あのカラムの代入は許可されている」と逆算しなくてはならないということです。

$fillableまたは$guardedを使う時に注意しなければならないこと

$request->all()を使わない

  • 理由は、特定のアクションで意図しない操作が行われる可能性があるからです。以下はその例です。
Post.php
    protected $fillable = [
        'key1',
        'key2',
        'key3'
    ];
PostController.php
public function update(Request $request,Post $post)
{
    $data = $request->all();
    $post->fill($data)->save();
}
  • このupdate()ではkey1とkey2の更新を想定していますが、key3が$dataにある場合、key3の値も更新してしまいます。
  • なので$request->only()を使い、意図しない操作を防ぐことを意識しましょう。

モデルの新規作成と更新

新規作成

  • $this->カラム = データでのやり方
    • 書くのが面倒。
    • $fillableまたは$guardedを無視する。
PostController.php
$post = new Post();
$post->store($data); // storeは自分で定義したもの
Post.php
public function store($data)
{
    $this->title = $data['title'];
    $this->content = $data['content'];

    $this->save();
}
  • モデル::createでのやり方
    • 簡潔で見やすい。
    • $fillableまたは$guardedを確認する。
PostController.php
Post::create($data);

更新

  • $this->カラム = データでのやり方
    • こちらも書くのが面倒。
    • $fillableまたは$guardedを無視する。
PostController.php
$post->updateContents($data); //updateContentsは自分で定義したもの
Post.php
public function updateContents($data)
{
    $this->title = $data['title'];
    $this->title = $data['content'];

    $this->save();
}
  • update()
    • 簡潔で見やすい。
    • $fillableまたは$guardedを確認する。
    • しかし、「LaravelのORMで初心者から職人へ」にも書いてある通り、直接SQLでデータを入れているため危険であることは認識しなければならない。
PostController.php
$post->update($data);

fill($data)->save()は新規作成と更新のどちらも可能

新規作成

  • $post->fill($data)->save()
    • インスタンスを作成するのが面倒。
    • $fillableまたは$guardedを確認する。
PostController.php
$post = new Post();
$post->fill($data)->save();

更新

PostController.php
$post->fill($data)->save();

上記を検討した上で、私が思うモデルの新規作成と更新のベストプラクティス

新規作成

  • モデル::create()

更新

  • fill($data)->save()

さいごに

いかがだったでしょうか。
まず、$fillableと$guardedについてですが、私は$fillableの方が$guardedより良いのではないかと考えます。なぜなら、繰り返しになりますが、すべてのカラムを把握しなくとも「どのカラムに対して値の代入が許可されているか」見てすぐわかるからです。
次にモデルの新規作成や更新の方法がそれぞれいくつかあることを確認しました。
私と同じく「そのような方法があったんだ!」と新たな発見をし、自身のコードを見直すきっかけになれれば幸いです。
ご指摘およびご意見お待ちしております。
それではまた!

参考サイト

9
6
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
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?