カテゴリー: おすすめ

  • 図解 初心者が Google Tag Mnager の設定をする方法

    図解 初心者が Google Tag Mnager の設定をする方法

    これは何?

    初めてGoogle Tag Mnager を実装する方向けの記事です。

    GTMを設定することでGoogleアナリティクスと連携して、
    サイトの訪問者がどこからきたのか、オーガニックサーチなのかTwitter, FacebookなどのSNSなのか、有料広告からなのか、といった流入元の追跡ができます。

    また、ユーザーのページ遷移をグラフィカルに分析することも可能です。

    この記事ではGTMとは何か?前提から設定方法まで図解でわかりやすく、順を追って解説します。

    この記事は2024年9月時点で最新の情報です。


    基本と前提

    グーグルタグマネージャーでは、
    Webサイトに埋め込まれたボタンのクリックや、
    他サイトからの遷移、スクロールのデータを収集できます。

    1つのGoogleアカウントに
    プロジェクトごとにGTMアカウントを作れます。

    コンテナはサービスごとに作成するのが良いでしょう。

    アカウント作成

    まずはタグマネージャーにアクセスします。
    https://tagmanager.google.com

    サイトにアクセスしたらアカウントを作成します。
    Googleアカウントをお持ちでしたら、手こずることはないでしょう。

    コンテナ作成

    コンテナはトラッキングコードを管理するバケツのようなものです。
    コンテナは通常サービスひとつに付き作成するものです。

    基本的に一つのドメインに1コンテナ作成します。
    このコンテナのひとまとまりで、タグを設定していきます。


    サイトに設定しよう

    WordPressをお使いの場合は、
    Google Site Kit のプラグインを使うのが最も簡単でしょう。

    WordPressの管理画面から Site Kit / Settings の順番にボタンを押していくと、設定の項目が出ると思います。

    詳しい設定方法はこちらの記事で解説しました。

    他サイトで他のプラグインを使う手段が紹介されていますが、
    24年9月現在WordPressユーザーはGoogle公式のSiteKitを使うのが英断です。

    その他のフレームワークをお使いの方は、
    Google Tag Mnager に最初に登録したときに、head, body に書くべきものの指示があるので、そちらに従ってください。

    最初のポップアップを消してしまった方は、
    ワークスペースの画面右上に GTMから始まるIDが書いてあります。
    そちらをクリックすると、設定方法のポップアップが再度開きます。

    正しく設定できたかの確認は、
    右上の「プレビュー」ボタンを押下すると、
    別ページが立ち上がり、出てきたURLに対してOKを押すと、
    自社サイトが立ち上がり、右下に次のようなポップアップが出ているはずです。

    Tag Assistant Connected とあれば正常に動作しています。

    タグ・トリガーと変数とは何か?

    次のセクションから具体的な使い方を解説します。
    タグマネージャーを使いこなすには基本的に以下の3つ

    • タグ
    • トリガー
    • 変数

    これを理解すれば十分扱えるようになります。

    タグとトリガーにはそれぞれ
    変数を設定することができます。

    GTMタグとトリガーと変数について

    タグ、トリガー、変数はそれぞれ、

    • 何をしたいか
    • いつするか
    • 正確には??

    を設定できます。

    タグとトリガーと変数の意味

    具体的には、

    • タグ
      • Googleアナリティクスを
    • トリガー
      • ページが開いたときに
    • 変数
      • 予約ページに遷移したか
      • 何秒スクロールできたか

    のように設定できます。

    タグマネージャータグとトリガーと変数の具体的な役割

    GA4との連携

    このセクション以降Googleアナリティクスとの連携にも触れますので、先にアナリティクスの設定もすませておいてください。
    https://analytics.google.com

    新しくタグを使いしましょう。

    タグのタブに移動して、左上の「新規」ボタンを押します。

    タグの設定をクリックします

    [Googleアナリティクス], [Googleタグ]の順番で選択していきます。

    タグIDにはアナリティクスのアカウントのタグIDをコピペしてください。

    測定IDは G- から始まる文字列です。

    タグIDはデータ[管理]の[データの収集と修正]で[データストリーム]をクリックすると、タグの設定内容が表示されます。

    これはアナリティクスの画面です。

    次にトリガーを押して、[initialization – All Pages]を選択します。

    All Pages を選択している記事もありますが、24年9月現在 initialization を選択するのが推薦です。

    できたら、名前を変更して、右上[保存]を押しましょう。

    これで完了です。

    Tag Assistant での確認

    右上プレビューから動作確認をしましょう。

    全てのページで Tag Assistant Connected になっていればOKです。

    GA4での確認

    次にGoogleアナリティクスの画面で確認します。

    GA4の画面を開いたら左のパネルから[⚙️管理]を選択します。

    下にスクロールすると、
    データの表示の中に[Debug View]の項目があります。
    これをクリックします。

    正しく実行できていれば、何時にトリガーが発火したかのログがここに記録されます。

    トリガーについて

    トリガーは発動(発火)条件のことです。
    どのタイミングで、データのカウントが行われるかを指します。

    トリガーの種類について

    トリガーには以下があります。
    箇条書きで簡単な内容をメモしました。
    (名前のままの動作のものは紹介を省略しています。)

    • ページビュー トリガー
      • ページが読み込まれた時
    • クリック トリガー
      • 全ての要素
        • リンク、画像、ボタンなど
      • リンクのみ
        • <a>タグなどのリンクの遷移のあるもののみ
    • 要素の表示トリガー
      • 選択した要素が、ユーザーに表示された際に発火
      • Id, Class タグに設定できる
    • フォーム送信トリガー
    • スクロール距離トリガー
      • ユーザーがどの程度スクロールしたかで発火
      • 縦方向、横方向に設定できる
    • YouTube動画トリガー
    • カスタムイベント トリガー
    • 履歴の変更
    • JavaScriptエラートリガー
    • タイマー トリガー
    • トリガー グループ

    参考:https://support.google.com/tagmanager/topic/7679108?sjid=14244337646739296041-AP


    テスト

    ワークスペース右上の「プレビュー」をクリックして、
    Google Tag Assistant を起動します。

    Chrome のプラグインの Tag Assistant を使おうという記事がありますが、既に使われなくなった古い方法です。


    公開

    ワークスペース右上の「公開」ボタンから、
    設定したものを本番環境に適応できます。

    バージョン管理機能もついています。

  • DS-lite, PPPoE, L2TP, PPTP, v6 plus, MAP-E の違いは?

    DS-lite, PPPoE, L2TP, PPTP, v6 plus, MAP-E の違いは?

    これは何?

    ルーターの設定中にインターネットの接続方式が色々とあり、
    どれがどういう意味なのかを調べた記事です。

    青背景は前提知識なので読み飛ばしていただいて構いません。

    解説?

    解説と言ってはなんですが、ちょっとしたまとめです。
    正しいか微妙なので、後述の参考文献をご確認ください。

    IPv4 とは?

    IPv4(Internet Protocol version 4)は、インターネット上でデータを送受信するための主要なプロトコルです。IPアドレスと呼ばれる32ビットの数値(例:192.168.0.1)を使って、ネットワーク上のデバイスを識別します。

    特徴

    • 32ビットのアドレス空間(約42億個のアドレス)
    • パケット通信を利用
    • サブネットマスクを使ってネットワークの区分けが可能

    IPv6 とは?


    IPv6(Internet Protocol version 6)は、IPv4の後継として開発されたプロトコルで、より多くのIPアドレスを提供します。128ビットのアドレス空間を持ち、IPv4に比べて遥かに多くのデバイスをユニークに識別できます

    IPv4 の課題

    1. アドレス枯渇

    IPv4の32ビットアドレス空間では約42億個のアドレスしか提供できません。
    インターネットの普及とともに、これらのアドレスが急速に枯渇しています 。
    そのため現在ではIPv4は各契約者ごとに振り分けれらるのではなく、プロバイダ側で一つの公的IPアドレスを使って複数の家庭で使えるように割り振っている場合があります。

    2. セキュリティ

    IPv4は設計上、セキュリティ機能が十分ではありません。IPsecなどのセキュリティ機能は追加できますが、デフォルトでは含まれていません。

    このような問題に対処するために、後述のDS-Lite や MAP-E が出てくるわけです。

    DS-Lite (Dual-Stack Lite)

    私は楽天ひかりを契約していのですが、標準の設定ではこちらの設定がお勧めされており、DS-Lite利用していました。

    DS-Liteは、IPv4アドレスの枯渇に対応するための技術で、IPv4パケットをIPv6パケットにカプセル化してインターネットに送る方法です。
    ユーザーが送信するIPv4パケットをIPv6パケットに包んでプロバイダに送り、プロバイダが再びIPv4パケットに戻してインターネットに接続します。

    ポイント

    • IPv4とIPv6を同時に使う
    • IPv4アドレスの枯渇問題に対応
    • NATがプロバイダー側で行われるので、ポートの解放が難しい

    MAP-E (Mapping of Address and Port using Encapsulation)

    MAP-Eは、IPv4アドレスの共有を可能にするIPv6移行技術です。
    IPv4パケットをIPv6にカプセル化し、IPv6インフラを利用してIPv4通信を行います。
    これにより、ISPは複数のユーザーが一つのIPv4アドレスを共有できるようになります  。

    ポイント

    • NAT がルーター側で行われるので、ポートの解放が可能

    PPPoE (Point-to-Point Protocol over Ethernet)

    PPPoEは、イーサネットネットワーク上でPPPセッションを確立し、ユーザー名とパスワードを使用して認証を行うプロトコルです。
    主にDSL接続で使用され、家庭内の複数のデバイスがインターネット接続を共有するのに適しています 。

    ポイント

    • 認証機能がある

    L2TP (Layer 2 Tunneling Protocol)

    L2TPは、VPN(仮想プライベートネットワーク)を確立するためのプロトコルです。
    PPTPとL2Fの機能を組み合わせており、PPPパケットをIPパケットにカプセル化してインターネット上で伝送します。
    L2TPは様々なネットワークタイプで使用でき、強力な暗号化と認証機能を提供します 。

    ポイント

    • VPNを作るために使用
    • 強力な暗号化と認証機能を提供
    • 多様なネットワークで使用可能

    PPTP (Point-to-Point Tunneling Protocol)


    PPTPもVPNを作るための技術ですが、L2TPほどのセキュリティはありません。
    リモートユーザーが安全にプライベートネットワークに接続するために使われます。

    ポイント

    • 簡単なVPNを作るために使用
    • セキュリティは低め
    • 古い技術で、新しい技術に置き換わりつつある

    v6プラス

    v6プラスは、IPv6とIPv4を同時に利用可能にする技術で、IPv6ネットワーク上でIPv4の通信を可能にします。これにより、IPv4アドレスの枯渇問題を解決しつつ、既存のIPv4サービスにもアクセスできます。

    NTT等がやってる日本の規格らしく?DS-Liteと似たような仕組みだなと思いました。

    結局?

    合ってるかわからないけど、総評。間違ってたらめちゃくちゃカスです。ごめんなさい。

    Pv4 は遅い云々の前に、そもそも枯渇してるから、
    1ルーターにつき一つじゃないから(数十家庭で1個のレベル?)ポートの解放が必要になる
    そうなるとv4 to v6の切り替えが発生する DS-Lite, Map-Eは難しい(少なくとも家庭用ルーターのtp-link archar ax10ではできない)から
    PPPoEにしなきゃいけないんだけど、これは認証の手間が入るから普段のネット回線でも使うルーターに割り当てるのは酷

    結局IPv6だとグローバルで、ネットワークに直結できるから(数がめちゃくちゃあるから機器ごとに持たせられるため?)
    PC側の設定だけで、ルーターはDS-Liteのまま公開できるという知見を得た。

    参考文献様

    DS-Lite とは?
    https://techlog.iij.ad.jp/archives/1254

  • MVVMとは?を理解するために簡単なアプリを作る with React

    MVVMとは?を理解するために簡単なアプリを作る with React

    ❓ これは何

    MVVMはフロントエンドの開発の設計モデルの一つです。
    今回はこれを理解するのに、React TS で簡単なタスク管理アプリを作ってみます。

    始めて React TS を始める人もついていける内容かと思います。
    15分程度でできるでしょう。

    完成すると次のようになります。

    🪴 環境

    2024年 7月16日(火) 執筆

    • apple M1 MacBook Air
    • 14.5(23F79)

    🛠️ やり方

    MVVMは、ソフトウェアアーキテクチャのデザインパターンの一つで、
    アプリケーションのロジックとUIを分離することを目的としています。

    主に3つの部分から構成されます

    1. Model(モデル): アプリケーションのデータとビジネスロジックを保持します。
    2. View(ビュー): ユーザーインターフェースを担当し、ユーザーの入力を受け付けます。
    3. ViewModel(ビューモデル): ViewとModelの間のインターフェースとして機能し、データバインディングとUIロジックを処理します。

    これを聞いても意味がわからないと思います。
    とりあえず簡単なタスク管理アプリを作りながら、考えていきましょう。

    🏃‍♀️ プロジェクトの作成

    プロジェクトを作成します。

    yarn create react-app task-tracker --template typescript

    プロジェクトフォルダに移動します。

    cd task-tracker

    起動します。

    yarn start

    ブラウザで一応確認

    📦 Model

    モデルは、アプリケーションのデータ構造を定義します。
    モデルはデータの保存、取得、操作を行います。

    今回は使っていませんが、
    データの永続化(データベースへの保存など)や
    外部からのデータ取得(APIからのデータ取得など)を担当します。

    src ディレクトリに models フォルダを作成し、
    中にTask.ts を作成します。

    export interface Task {
      id: number;
      title: string;
      completed: boolean;
    }

    🚀 ViewModel

    ビューモデルは、モデルとビューの間の橋渡しを行います。
    タスクの追加、完了状態の切り替え、削除のロジックを管理します。

    src/models ディレクトリに TaskViewModel.tsx を作成

    このコードは、タスクの状態を管理するためのフックを定義しています。
    useTaskViewModelフックを使用することで、タスクの追加、完了状態の切り替え、削除が簡単に行えます。

    import { useState } from 'react';
    import { Task } from './Task';
    
    export const useTaskViewModel = () => {
      const [tasks, setTasks] = useState<Task[]>([]);
    
      const addTask = (title: string) => {
        const newTask: Task = {
          id: Date.now(),
          title,
          completed: false,
        };
        setTasks([...tasks, newTask]);
      };
    
      const toggleTaskCompletion = (id: number) => {
        setTasks(tasks.map(task => 
          task.id === id ? { ...task, completed: !task.completed } : task
        ));
      };
    
      const deleteTask = (id: number) => {
        setTasks(tasks.filter(task => task.id !== id));
      };
    
      return {
        tasks,
        addTask,
        toggleTaskCompletion,
        deleteTask,
      };
    };

    🐏 Model, View があれば ViewModel いらなくない?

    モデルとビューだけではコードが煩雑になります。

    • ビューが直接モデルを操作すると、ビューにロジックが含まれることになります。
      これにより、ビューが単純に見た目のみの表現でなくなってしまうので、再利用性が低くなります。
    • ViewModelがあると単純にテストがしやすくなります。パラメータの調整も楽です。

    👀 View

    ビューは、ユーザーインターフェースを担当し、ユーザーの操作を受け付けます。
    ここでは、タスクのリスト表示とタスクの追加を行うコンポーネントを作成します。

    src/components ディレクトリに TaskList.tsx を作成

    タスクをリスト表示し、完了状態の切り替えや削除を行うコンポーネントです。

    // src/components/TaskList.tsx
    import React from 'react';
    import { Task } from '../models/Task';
    
    interface TaskListProps {
      tasks: Task[];
      onToggle: (id: number) => void;
      onDelete: (id: number) => void;
    }
    
    const TaskList: React.FC<TaskListProps> = ({ tasks, onToggle, onDelete }) => {
      return (
        <ul>
          {tasks.map(task => (
            <li key={task.id}>
              <input 
                type="checkbox" 
                checked={task.completed} 
                onChange={() => onToggle(task.id)} 
              />
              {task.title}
              <button onClick={() => onDelete(task.id)}>Delete</button>
            </li>
          ))}
        </ul>
      );
    };
    
    export default TaskList;

    src/components ディレクトリに AddTask.tsx を作成

    // src/components/AddTask.tsx
    import React, { useState } from 'react';
    
    interface AddTaskProps {
      onAdd: (title: string) => void;
    }
    
    const AddTask: React.FC<AddTaskProps> = ({ onAdd }) => {
      const [title, setTitle] = useState('');
    
      const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        if (title.trim()) {
          onAdd(title);
          setTitle('');
        }
      };
    
      return (
        <form onSubmit={handleSubmit}>
          <input 
            type="text" 
            value={title} 
            onChange={(e) => setTitle(e.target.value)} 
            placeholder="Add a new task" 
          />
          <button type="submit">Add</button>
        </form>
      );
    };
    
    export default AddTask;

    🍳 仕上げ

    最後に、AppコンポーネントでこれらのコンポーネントとViewModelを統合します。

    プロジェクトの基本となる App.tsx を次のように書き換えます。

    この構造により、アプリケーションのロジック(タスクの追加、完了状態の切り替え、削除)はViewModelに集中します。

    ビューはデータの表示とユーザーの入力を受け取ることに専念できます。
    これにより、コードの再利用性とテスト容易性が向上します。

    // src/App.tsx
    import React from 'react';
    import './App.css';
    import { useTaskViewModel } from './models/TaskViewModel';
    import TaskList from './components/TaskList';
    import AddTask from './components/AddTask';
    
    const App: React.FC = () => {
      const { tasks, addTask, toggleTaskCompletion, deleteTask } = useTaskViewModel();
    
      return (
        <div className="App">
          <h1>Task Tracker</h1>
          <AddTask onAdd={addTask} />
          <TaskList 
            tasks={tasks} 
            onToggle={toggleTaskCompletion} 
            onDelete={deleteTask} 
          />
        </div>
      );
    };
    
    export default App;

    以上です!
    これでできたはず!!

  • MVC とは?を理解するために簡単なアプリをつくる with Laravel

    MVC とは?を理解するために簡単なアプリをつくる with Laravel

    ❓ これは何

    ソフトウェアを構築するには、様々な設計モデルがあります。

    今回はバックエンドの開発で基礎的で代表的なMVCモデルを少しわかったつもりになるために、
    簡単なメモアプリを作ります。

    この記事では Laravel を使っています。
    まだ Hello World ができていない方は、先に済ませておきましょう。
    M1 mac でLaravel のHelloWorldする方法

    このページでの🐏はコラムです。読み飛ばしてOKです。

    今回完成すると次のようなものになります。
    この記事ではスタイリングなどの解説はしていません。
    1時間内でとりあえず作ることを目標にしています。

    🪴 環境

    この記事では Apple Silicon に合わせた書き方になっている箇所があります。(Docker関係)
    ご注意ください。

    • Apple m1 MacBook Air
    • 14.5(23F79)

    🔧 やり方

    MVC(Model-View-Controller)は、ソフトウェア設計の基本原則の一つです。

    アプリケーションの構造を

    • Model
    • View
    • Controller

    の3つの部分に分けることで、保守性と可読性を向上させます。

    🐳 初期設定

    ここではApple m1 での設定となっています。
    主にDockerに関する操作についてです。

    docker-compose.yml は次のようにしました。

    version: '3.8'
    services:
      app:
        build:
          context: .
          dockerfile: Dockerfile
        image: laravel-app
        container_name: laravel-app
        restart: unless-stopped
        working_dir: /var/www
        volumes:
          - .:/var/www
        networks:
          - laravel
        environment:
          - DB_CONNECTION=mysql
          - DB_HOST=db
          - DB_PORT=3306
          - DB_DATABASE=your_database_name
          - DB_USERNAME=your_database_user
          - DB_PASSWORD=your_database_password
    
      webserver:
        image: arm64v8/nginx:alpine
        container_name: webserver
        restart: unless-stopped
        ports:
          - "8000:80"
        volumes:
          - .:/var/www
          - ./nginx.conf:/etc/nginx/conf.d/default.conf
        networks:
          - laravel
    
      db:
        image: arm64v8/mariadb:10.5
        container_name: db
        restart: unless-stopped
        environment:
          - MYSQL_ROOT_PASSWORD=root_password
          - MYSQL_DATABASE=your_database_name
          - MYSQL_USER=your_database_user
          - MYSQL_PASSWORD=your_database_password
        volumes:
          - dbdata:/var/lib/mysql
        ports:
          - "3306:3306"
        networks:
          - laravel
    
    volumes:
      dbdata:
    
    networks:
      laravel:
        driver: bridge

    .env ファイルに次のコードを追記します。

    DB_CONNECTION=mysql
    DB_HOST=mysql
    DB_PORT=3306
    DB_DATABASE=your_database_name
    DB_USERNAME=your_database_user
    DB_PASSWORD=your_database_password

    コンテナを起動し、コンテナにアクセスします。

    docker-compose up -d
    docker-compose exec app bash

    migrate したら exit します。

    php artisan migrate

    マイグレーションファイルの作成

    Laravelでは、マイグレーションファイルを使ってデータベーススキーマ(スキーマとは簡単にいうと構造のこと)の変更を定義します。
    マイグレーションファイルは、PHPコードでデータベースのテーブルやカラムの追加、削除、変更を記述します。

    database/migrationsディレクトリに新しいマイグレーションファイルを生成します。

    notes というテーブルが作成されます。

    実行後、database/migrations/ホゲホゲcreate_notes_table.php というファイルが作成されていると思います。(ホゲホゲには日付などが入っているはず)

    php artisan make:migration create_notes_table --create=notes

    🐏 php artisan とは?

    • command: 実行するコマンド(例: make:migration, serve, migrateなど)
    • options: オプションとして指定するもの(例: –force, –quietなど)
    • arguments: コマンドに渡す引数(例: マイグレーションの名前など)
    php artisan [command] [options] [arguments]

    create_notes_table.php

    function up()の中身を次のように追記します。

    upメソッド
    マイグレーションを適用する際に実行されます。
    例では、notesテーブルを作成し、
    id, title, content, timestamps
    のカラムを定義しています。

    downメソッド
    マイグレーションをロールバックする際に実行されます。
    例では、notesテーブルを削除しています。
    ロールバックとはデータベースのマイグレーションを元に戻す操作を指します。具体的には、適用されたマイグレーションを取り消し、以前の状態に戻すことです。

    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    return new class extends Migration
    {
        /**
         * Run the migrations.
         */
        public function up(): void
        {
            Schema::create('notes', function (Blueprint $table) {
                $table->id();
                $table->string('title');
                $table->text('content');
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         */
        public function down(): void
        {
            Schema::dropIfExists('notes');
        }
    };
    

    マイグレーションを実行します。
    このコマンドで上記コードのupが実行されることになります。。

    php artisan migrate

    📦 MODEL

    メモモデルの作成

    モデルはデータベースとのやり取りや、データの検証の実装を担当します。

    メモアプリケーションでは、Noteモデルがこれに該当します。Noteモデルはメモのデータ(タイトルと内容)を管理します

    メモモデルの作成

    php artisan make:model Note

    modelsの中の Note.php に次のコードを記述します。

    use HasFactory;
    Laravelのファクトリ機能を使用します。

    protected $fillable = [‘title’, ‘content’];:
    マスアサインメントを許可する属性を指定します。

    マスアサインメント(Mass Assignment)とは、配列やオブジェクトからモデルの複数の属性に一括で値を割り当てることです。

    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Note extends Model
    {
        use HasFactory;
    
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        protected $fillable = [
            'title',
            'content',
        ];
    }

    🐏 use HasFactory; とは?

    ファクトリは、テストデータを作成するクラスであるFactoryを使用して、データベーステーブルにランダムなデータを生成する機能です。

    🎮 CONTROLLER

    controller の作成

    コントローラーはユーザーの入力に応じてモデルとビューを調整します。
    リクエストを受け取り、適切なモデルとビューを呼び出してレスポンスを返します。

    メモアプリケーションでは、NoteControllerがコントローラーに該当します。
    NoteControllerはメモの作成、表示、編集、削除のロジックを担当します。

    メモコントローラの作成

    php artisan make:controller NoteController --resource

    app/Http/Controllers/NoteController.php に次のコードを追加します。

    各メソッドは、特定のアクション(一覧表示、作成、保存、表示、編集、更新、削除)を担当します。

    リクエストを処理し、適切なビューを返します。

    $request->validate([
           'title' => 'required',  // タイトルは必須
           'content' => 'required', // 内容も必須
    ]);

    こういった書き方で、バリデーションを実装できます。

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Models\Note;
    use Illuminate\Http\Request;
    
    class NoteController extends Controller
    {
        // メモの一覧を表示するメソッド
        public function index()
        {
            // データベースからすべてのメモを取得
            $notes = Note::all();
            
            // 'notes.index'ビューを表示し、取得したメモをビューに渡す
            return view('notes.index', compact('notes'));
        }
    
        // 新しいメモを作成するフォームを表示するメソッド
        public function create()
        {
            // 'notes.create'ビューを表示
            return view('notes.create');
        }
    
        // 新しいメモを保存するメソッド
        public function store(Request $request)
        {
            // リクエストデータをバリデート
            $request->validate([
                'title' => 'required',  // タイトルは必須
                'content' => 'required', // 内容も必須
            ]);
    
            // リクエストデータを使って新しいメモを作成
            Note::create($request->all());
    
            // メモの一覧ページにリダイレクトし、成功メッセージを表示
            return redirect()->route('notes.index')
                            ->with('success', 'Note created successfully.');
        }
    
        // 特定のメモを表示するメソッド
        public function show(Note $note)
        {
            // 'notes.show'ビューを表示し、特定のメモをビューに渡す
            return view('notes.show', compact('note'));
        }
    
        // 特定のメモを編集するフォームを表示するメソッド
        public function edit(Note $note)
        {
            // 'notes.edit'ビューを表示し、特定のメモをビューに渡す
            return view('notes.edit', compact('note'));
        }
    
        // 特定のメモを更新するメソッド
        public function update(Request $request, Note $note)
        {
            // リクエストデータをバリデート
            $request->validate([
                'title' => 'required',  // タイトルは必須
                'content' => 'required', // 内容も必須
            ]);
    
            // 特定のメモを更新
            $note->update($request->all());
    
            // メモの一覧ページにリダイレクトし、成功メッセージを表示
            return redirect()->route('notes.index')
                            ->with('success', 'Note updated successfully');
        }
    
        // 特定のメモを削除するメソッド
        public function destroy(Note $note)
        {
            // 特定のメモを削除
            $note->delete();
    
            // メモの一覧ページにリダイレクトし、成功メッセージを表示
            return redirect()->route('notes.index')
                            ->with('success', 'Note deleted successfully');
        }
    }

    ルートの設定

    ルートの設定

    routes/web.php に次のコードを追記します。

    <?php
    
    use Illuminate\Support\Facades\Route;
    use App\Http\Controllers\NoteController;
    
    Route::get('/', [NoteController::class, 'index']);
    
    Route::resource('notes', NoteController::class);

    👁️ VIEW

    Viewの作成

    ビューはユーザーインターフェースを表示します。
    データの表示やユーザーの入力を受け付けます。

    メモアプリケーションでは、index.blade.php、create.blade.php、edit.blade.php、show.blade.phpがビューに該当します。
    これらのビューは、メモのリスト表示、作成フォーム、編集フォーム、詳細表示を担当します。

    まずは resources/views に layout.blade.php を作ります。

    共通レイアウトを定義し、各ビューで使用します。
    ヘッダーやフッターなど、どのページでも使うものもここに書いておくと、このファイルの役割がわかりやすいでしょう。

    <!DOCTYPE html>
    <html>
    <head>
        <title>Memo App</title>
    </head>
    <body>
        @yield('content')
    </body>
    </html>

    Resources/views フォルダに notes というディレクトリを作り、下記ファイルを作成します。

    • index.blade.php
    • create.blade.php
    • edit.blade.php
    • show.blade.php

    index.blade.php

    メモの一覧を表示し、各メモに対して詳細表示、編集、削除のリンクがあります。

    @extends('layout')
    
    @section('content')
        <h1>Notes</h1>
        <a href="{{ route('notes.create') }}">Create a new note</a>
        <ul>
            @foreach ($notes as $note)
                <li>
                    <a href="{{ route('notes.show', $note->id) }}">{{ $note->title }}</a>
                    <a href="{{ route('notes.edit', $note->id) }}">Edit</a>
                    <form action="{{ route('notes.destroy', $note->id) }}" method="POST">
                        @csrf
                        @method('DELETE')
                        <button type="submit">Delete</button>
                    </form>
                </li>
            @endforeach
        </ul>
    @endsection

    🐏 hoge.blade.php とは?

    hoge.blade.php とかくと、Laravelが提供するテンプレートエンジンの「Blade」が使用できます。
    BladeはPHPのテンプレートエンジンで、HTML, PHP をより見やすく、書きやすくすることが出来ます。

    • @extends(‘layout’)は、layout.blade.phpを継承することを示しています。
    • @section(‘content’)と@endsectionの間に、レイアウトに挿入するコンテンツを記述します。
    • @foreachループを使って、$notesコレクションの各メモを表示します。
    • @csrfはCSRFトークンを生成し、フォームの送信を保護します。
    • @method(‘DELETE’)はHTMLフォームでDELETEメソッドを使うためのBladeディレクティブです。

    🐏 CSRFトークンとは?

    CSRF(Cross-Site Request Forgery、クロスサイトリクエストフォージェリ)は、
    ユーザーが意図しないリクエストをWebアプリケーションに送信する攻撃です。
    CSRFトークンは、この攻撃を防ぐために使用されるセキュリティ機構です。

    基本的にPOSTの時には @csrf と書いておけばいいでしょう()

    create.blade.php

    メモの作成フォームです。

    @extends('layout')
    
    @section('content')
        <h1>Create Note</h1>
        <form action="{{ route('notes.store') }}" method="POST">
            @csrf
            <label>Title:</label>
            <input type="text" name="title">
            <label>Content:</label>
            <textarea name="content"></textarea>
            <button type="submit">Create</button>
        </form>
    @endsection

    edit.blade.php

    メモの編集フォームです。

    @extends('layout')
    
    @section('content')
        <h1>Edit Note</h1>
        <form action="{{ route('notes.update', $note->id) }}" method="POST">
            @csrf
            @method('PUT')
            <label>Title:</label>
            <input type="text" name="title" value="{{ $note->title }}">
            <label>Content:</label>
            <textarea name="content">{{ $note->content }}</textarea>
            <button type="submit">Update</button>
        </form>
    @endsection

    show.blade.php

    メモの詳細画面です。

    @extends('layout')
    
    @section('content')
        <h1>{{ $note->title }}</h1>
        <p>{{ $note->content }}</p>
        <a href="{{ route('notes.index') }}">Back to Notes</a>
    @endsection

    これで完成です!
    実行し、確認してみましょう。

Home
About
Blog
Works
Contact