趣味マッチングアプリの作り方(Laravel)

## Laravel、Tailwind CSS、AIを使って

今回は、Laravel、Tailwind CSS、AIを使って趣味マッチングアプリを作る方法をご紹介します。

このアプリでは、ユーザーがログインし、AIが同じ趣味を持つ近いユーザーをマッチングし、WhatsApp風のチャット機能を提供します。

## 1. プロジェクトのセットアップ

まず、Laravelプロジェクトを作成し、Tailwind CSSをインストールします。

```bash
composer create-project laravel/laravel hobby-matching-app
cd hobby-matching-app
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npx tailwindcss init -p
```

`tailwind.config.js`を編集します：

```javascript
module.exports = {
  content: [
    './resources/**/*.blade.php',
    './resources/**/*.js',
    './resources/**/*.vue',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

`resources/css/app.css`を編集：

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

## 2. ユーザー認証の実装

Laravelの認証機能を使用します。

```bash
php artisan ui vue --auth
npm install && npm run dev
```

## 3. 趣味選択機能の開発

`Hobby`モデルと`UserHobby`モデルを作成します。

```bash
php artisan make:model Hobby -m
php artisan make:model UserHobby -m
```

マイグレーションファイルを編集：

```php
// database/migrations/xxxx_xx_xx_create_hobbies_table.php
public function up()
{
    Schema::create('hobbies', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });
}

// database/migrations/xxxx_xx_xx_create_user_hobbies_table.php
public function up()
{
    Schema::create('user_hobbies', function (Blueprint $table) {
        $table->id();
        $table->foreignId('user_id')->constrained();
        $table->foreignId('hobby_id')->constrained();
        $table->timestamps();
    });
}
```

## 4. AIマッチング機能の実装

`MatchingController`を作成します：

```bash
php artisan make:controller MatchingController
```

`MatchingController.php`を編集：

```php
namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class MatchingController extends Controller
{
    public function findMatches(Request $request)
    {
        $user = $request->user();
        $userHobbies = $user->hobbies->pluck('id');
        $matches = User::whereHas('hobbies', function ($query) use ($userHobbies) {
            $query->whereIn('hobby_id', $userHobbies);
        })->where('id', '!=', $user->id)->get();

        return view('matches', compact('matches'));
    }
}
```

## 5. チャット機能の実装

`Message`モデルとコントローラーを作成：

```bash
php artisan make:model Message -mc
```

`Message`モデルを編集：

```php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    use HasFactory;

    protected $fillable = ['sender_id', 'receiver_id', 'content'];

    public function sender()
    {
        return $this->belongsTo(User::class, 'sender_id');
    }

    public function receiver()
    {
        return $this->belongsTo(User::class, 'receiver_id');
    }
}
```

`MessageController`を編集：

```php
namespace App\Http\Controllers;

use App\Models\Message;
use Illuminate\Http\Request;

class MessageController extends Controller
{
    public function store(Request $request)
    {
        $message = Message::create([
            'sender_id' => $request->user()->id,
            'receiver_id' => $request->receiver_id,
            'content' => $request->content,
        ]);

        return response()->json($message);
    }

    public function getMessages(Request $request, $receiverId)
    {
        $messages = Message::where(function ($query) use ($request, $receiverId) {
            $query->where('sender_id', $request->user()->id)
                  ->where('receiver_id', $receiverId);
        })->orWhere(function ($query) use ($request, $receiverId) {
            $query->where('sender_id', $receiverId)
                  ->where('receiver_id', $request->user()->id);
        })->orderBy('created_at', 'asc')->get();

        return response()->json($messages);
    }
}
```

## 6. フロントエンドの実装

`resources/views/matches.blade.php`を作成：

```html
<x-app-layout>
    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    <h2 class="text-2xl font-bold mb-4">マッチングユーザー</h2>
                    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                        @foreach ($matches as $match)
                            <div class="bg-gray-100 p-4 rounded-lg">
                                <h3 class="text-xl font-semibold">{{ $match->name }}</h3>
                                <p class="text-gray-600">趣味: {{ $match->hobbies->pluck('name')->implode(', ') }}</p>
                                <a href="{{ route('chat', $match->id) }}" class="mt-2 inline-block bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">チャットを開始</a>
                            </div>
                        @endforeach
                    </div>
                </div>
            </div>
        </div>
    </div>
</x-app-layout>
```

これで、趣味マッチングアプリの基本的な実装が完了しました。AIマッチングのロジックやチャット機能の詳細な実装は、プロジェクトの要件に応じてさらにカスタマイズしてください。

このアプリを作ることで、Laravel、Tailwind CSS、AIの実践的なスキルを身につけることができます。ぜひチャレンジしてみてください！