Laravelデータベースモデルでのスネークケースからキャメルケースへの自動変換

概要

データベース設計ではスネークケース(snake_case)を採用し、アプリケーションコードではキャメルケース(camelCase)を使用したいケースは多いでしょう。Laravel標準のEloquentではこの自動変換機能がないため、eloquenceパッケージの活用を推奨します。

インストール

composer require kirkbushell/eloquence

サービスプロバイダーの登録

config/app.phpファイルにサービスプロバイダーを追加します。

'providers' => [
    /*
     * Application Service Providers...
     */
    Eloquence\EloquenceServiceProvider::class,
],

モデルの設定

変換対象のモデルでCamelCasingトレイトをuseします。

<?php
namespace App\Models;

use Eloquence\Behaviours\CamelCasing;
use Illuminate\Database\Eloquent\Model;

class ContactForm extends Model
{
    use CamelCasing;

    protected $table = 'contact_forms';
    protected $primaryKey = 'id';
    protected $guarded = [];
    public $timestamps = false;
}

主要なポイント

1. 保存時の自動変換

モデルのプロパティへ値を代入する際、スネークケースでもキャメルケースでも問題ありません。パッケージ内部でStr::snake()メソッドが呼ばれるため、自動的に適切な変換が行われます。

// 両方の方法で代入可能
$contact = new ContactForm();
$contact->userName = 'テストユーザー';
// または
$contact['user_name'] = 'テストユーザー';

$contact->save();

データベースのフィールドはuser_nameとして保存されます。

2. 取得データの自動変換

データを取得时会自动将スネークケースからキャメルケースに変換されます。

{
    "code": 200,
    "msg": "成功",
    "data": {
        "total": 2,
        "items": [
            {
                "id": 13,
                "userName": "ユーザーA",
                "email": "test@example.com",
                "message": "お問い合わせ内容",
                "createdAt": "2023-06-21 09:58:23",
                "updatedAt": "2023-06-21 09:58:23",
                "platform": "PC",
                "language": "ja-JP"
            }
        ]
    }
}

元々のデータベーステーブル構造:

CREATE TABLE `contact_forms` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
 `user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'ユーザー名',
 `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'メールアドレス',
 `message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT 'メッセージ内容',
 `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '作成日時',
 `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日時',
 `platform` varchar(10) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'PC' COMMENT 'プラットフォーム',
 `language` varchar(10) COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'ja-JP' COMMENT '言語',
 PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='お問い合わせフォーム';

3. リレーションを使用した取得

リレーションを含む場合も自動的に変換されます。

$articles = Article::with(['author'])->get();
class Article extends Model
{
    use CamelCasing;

    protected $table = 'articles';
    protected $primaryKey = 'id';
    protected $guarded = [];

    public $timestamps = false;

    public function author()
    {
        return $this->hasOne(User::class, 'id', 'author_id');
    }
}

返り値例:

{
    "id": 37,
    "title": "記事タイトル",
    "authorId": 5,
    "content": "記事内容...",
    "publishedAt": "2022-01-21 15:50:50",
    "modifiedAt": "2022-01-23 22:52:56",
    "thumbnailUrl": "/upload/image/20230101/sample.jpg",
    "status": "published",
    "language": "ja-JP",
    "author": {
        "id": 5,
        "name": "管理者",
        "email": "admin@example.com",
        "createdAt": "2022-01-21 15:45:09",
        "updatedAt": "2023-03-21 08:31:03"
    }
}

4. アクセサーとミューテタの活用

独自の属性アクセス処理を定義しても、キャメルケースでの返回変換に影響しません。

class ContactForm extends Model
{
    use CamelCasing;

    protected $table = 'contact_forms';
    protected $primaryKey = 'id';
    protected $guarded = [];

    public $timestamps = false;

    public function getUserNameAttribute($value)
    {
        return !empty($value) ? json_decode($value, true) : '';
    }

    public function setUserNameAttribute($value)
    {
        $this->attributes['user_name'] = !empty($value) ? json_encode($value) : '';
    }
}

5. FAQ

  • なぜキャメルケース変換が必要?:Laravelのクラス名、メソッド名、変数名は慣例的にキャメルケースを使用するため、コードの統一性を保つことができます
  • スネークケースだけで運用不行吗?:問題ありません。各プロジェクトの運用方針に応じて選択してください
  • キャメルケースだけで運用不行吗?:問題ありません。特に問題はありません
  • 変換プラグインが必要な理由:開発者可惯に応じたコード記述を可能にし、コードスタイルの統一性を保つためです

制限事項

以下のケースでは自動変換が機能しません。

// updateメソッド使用時
User::where('name', 'admin')->update([
    'authToken' => $token, 
    'tokenExpireAt' => date('Y-m-d H:i:s', time())
]);
SQL: update `users` set `auth_token` = xxx, `token_expire_at` = 2023-06-25 09:00:26 where `name` = admin

// getメソッドでカラム指定時
User::get(['id', 'tokenExpireAt']);
SQL: select `id`, `token_expire_at` from `users`

// 複雑なWHERE句や原生SQL使用時
DB::select('SELECT * FROM users WHERE token_expire_at > ?', [$date]);

これらの場合、配列で指定したカラム名の自動変換は行われません。

タグ: laravel eloquent database camelcase snakecase

5月19日 17:37 投稿