ハジメトーク最新記事

ハジメクリエイト社員による、日々の業務やトレンド、日常のアレコレについてお届けします。

もっと見る

【Laravel】created_atがNULLになる怪奇現象。

2026.04.03

1. 発生した事象:「あれ?タイムスタンプが入ってない…」

多対多のリレーション(Many-to-Many)を実装し、テストデータを保存してみたときのことです。

データベースを確認すると、レコード自体は正しく作成されているのに、なぜか created_at と updated_at のカラムだけが NULL になっていました。

「Modelの設定漏れかな?」と思い確認しましたが、特に問題はありません。

  • マイグレーションファイルには $table->timestamps() がある。
  • Modelに public $timestamps = false; とは書いていない(デフォルトの true のまま)。

なぜ、日時だけが入らないのでしょうか?

2. 原因:犯人は「保存に使ったメソッド」

モデルの設定ではなく、データの保存方法に原因がありました。

コードを見直してみると、その保存処理では create()save() ではなく、リレーションの sync() メソッドを使っていました。

PHP

// 例:ニュース記事(News)に配信先ユーザー(User)を紐付ける処理
$news->users()->sync($userIds);

実は、Laravelの多対多リレーションで使われる attach()sync() といったメソッドは、デフォルトでは中間テーブルのタイムスタンプを更新しない仕様になっています。

3. そもそも「sync()メソッド」とは?

ここで、今回使用した sync() メソッドについて少し解説します。

sync() は、多対多のリレーションを**「指定したIDのリストと同期させる」**ための非常に便利なメソッドです。

例えば、ある記事に紐づくタグIDが現在 [1, 2] だとします。

ここで $post->tags()->sync([2, 3]) を実行すると、Laravelは以下の処理を自動で行ってくれます。

  1. 追加: ID 3 は新しいので、中間テーブルに attach(挿入)する。
  2. 維持: ID 2 はリストに含まれているので、そのまま残す。
  3. 削除: ID 1 はリストに含まれていないので、中間テーブルから detach(削除)する。

自分で「どれを追加して、どれを削除するか」という差分計算をする必要がないため、多対多の保存処理では頻繁に利用されます。

しかし、この sync() はパフォーマンスを考慮してクエリビルダに近い軽量な動作をするため、Eloquentモデルの create() のように「自動で日時を入れる」というお節介(機能)が働きません。これが今回の「日時がNULLになる」原因でした。

4. 解決策:withTimestamps() を追加するだけ

原因がわかれば修正は簡単です。

リレーションを定義しているモデル(この例では News.php)に、「このリレーションではタイムスタンプも更新してね」と教えてあげるだけです。

belongsToMany の定義に ->withTimestamps() をチェーンさせます。

PHP

// app/Models/News.php

class News extends Model
{
    // ...

    public function users()
    {
        return $this->belongsToMany(User::class, 'news_users')
            ->withTimestamps(); // ★これを追加!
    }
}

これで、次回から sync() を実行した際に、自動的に現在時刻が created_atupdated_at に保存されるようになります。

5. まとめ

今回の落とし穴は、保存に使うメソッドによって「タイムスタンプの自動更新」の挙動が異なる点でした。

  • Model::create() / $model->save()
    • Eloquentが面倒を見てくれるので、自動で日時が入る
  • $relation->sync()
    • 差分更新をしてくれる便利なメソッドだが、デフォルトでは日時が入らない(NULLになる)
    • 有効にするにはリレーション定義に withTimestamps() が必要。

便利なメソッドを使うときは、その裏側の仕様も理解しておく必要がありますね。「モデルの設定は合っているのに日時が入らない」という現象に遭遇したら、まずはリレーション定義を確認してみてください。


この構成であれば、sync メソッドを知らない読者に対しても親切ですし、「なぜ罠にハマったのか(便利だから使っていたが、仕様を知らなかった)」という文脈が自然に伝わるかと思います。


🏢 株式会社ハジメクリエイトについて

この記事は、 株式会社ハジメクリエイト のエンジニアが執筆しました。


💻 Webシステム開発のプロフェッショナル

私たちは、ビジネスの成長をサポートするため、 PHPを用いたオーダーメイドのシステム開発 を提供しています。
お客様一人ひとりのニーズに応じたカスタムシステムを、 企画から開発・運用まで一貫してサポート
さらに、 React Nativeを活用したiOS/Android対応のアプリ開発 も得意としています。

単に「作る」だけでなく、
課題の本質に向き合い、最適な解決策を提案する のがハジメクリエイトのスタイルです。


🧑‍💻 一緒に働く仲間を探しています!

株式会社ハジメクリエイトでは、 自ら考え行動できるエンジニア を募集しています。
「私はこれがしたい!」という想いを持つあなた、一緒にモノづくりを楽しみませんか?

  • 技術で人の役に立ちたい
  • 意見が通る小さなチームで働きたい
  • フロントエンドもバックエンドも、いろいろ挑戦してみたい
  • お客さんと一緒にプロジェクトを育てたい

そんな気持ちがある方なら、きっと居心地のいい環境だと思います。
正社員はもちろん、パートタイムでの参加も歓迎中! 柔軟な関わり方で、あなたらしく働いてください。

👉 採用情報を見る
👉 お問い合わせはこちら


ちょっとでも「この会社、気になるな」と思ったら、ぜひお気軽にご連絡ください📩
最後まで読んでいただきありがとうございました!

  • Web技術

この記事を書いた人

Sho Tsukamoto

Chief Engineer Sho Tsukamoto

2023年4月入社。Web職人のたまごです。 最近はもっぱらコーディングすることは少なく、LaravelやReact Nativeを用いたシステム開発をメインとしています。

Sho Tsukamotoの書いた記事一覧へ

ハジメクリエイトでは一緒に働く仲間を募集しています!

関連記事