0
0

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 1 year has passed since last update.

【Laravel】Web開発初心者が1週間で入門チュートリアルを実施した記録(4)

Last updated at Posted at 2022-03-17

以下の続き。

フォルダ一覧までは作成できた。
■(1)〜(3)の復習:
・環境構築と設計
・開発のざっくり流れ
①ルーティング設定(web.php)
②コントローラーの作成・記載
③マイグレーションファイルの作成・記載
④マイグレーションの実行
⑤モデルクラスの作成
⑥テストデータの挿入
⑦コントローラーの追記・修正
⑧テンプレートの作成
・ルーティング設定(web.php)の記載方法

Route::get('/folders/{id}/tasks', 'TaskController@index')->name('tasks.index');

→getで/folders/{id}/tasksにリクエストがきたら、TaskControllerのindexメソッドを呼び出す。
  これを'tasks.index'と名づける。

・コントローラーの生成コマンド

php artisan make:controller (コントローラーの名前)

・マイグレーションファイルの生成コマンド

php artisan make:migration create_(テーブル名)_table --create=(テーブル名)

→database/migrations ディレクトリに YYYY_MM_DD_hhmmss_create_folders_table.phpが生成される。

・マイグレーションの実行コマンド

php artisan migrate

・モデルクラスの生成コマンド

php artisan make:model (モデル名)

・View関数の使い方

public function index ()
{
  $var = 'XXX';

    return view('aaa', ['varvar' => $var]);
}

上記のコードのように書けば「resources/views/aaa.blade.php」ビューへ、'varvar'という変数名で$varを渡すことができます。第二引数は"['渡す先での変数名' => 今回渡す変数]"。

・route関数の使い方

    @foreach($folders as $folder)
      <a href="{{ route('tasks.index', ['id' => $folder->id]) }}" class="list-group-item">
        {{ $folder->title }}
      </a>
    @endforeach

route関数の第一引数はルート名、第二引数は、ルート URL のうち変数になっている部分(ここでは {id})に実際の値を埋める)。

'tasks.index'は以下のルートで、{id}にはループで回しているfolderのidが入る。

Route::get('/folders/{id}/tasks', 'TaskController@index')->name('tasks.index');

ここまでが(1)~(3)の復習。

入門Laravelチュートリアル (4) ToDoアプリのタスク一覧表示機能を作る

フォルダ一覧の次はタスク一覧をつくった。

①、②は済みのため、Taskテーブルのマイグレーションファイル作成からスタート。

①ルーティング設定(web.php)
→記載済み。
②コントローラーの作成・記載
→TaskController作成済み
③マイグレーションファイルの作成・記載
④マイグレーションの実行
⑤モデルクラスの作成
⑥テストデータの挿入
⑦コントローラーの追記・修正
⑧テンプレートの作成

③マイグレーションファイルの作成・記載

php artisan make:migration create_tasks_table --create=tasks

上記コマンドで生成されたマイグレーションファイルをテーブル定義に従って修正。

// 外部キーを設定する
$table->foreign('folder_id')->references('id')->on('folders');

外部キー制約について。
上記では、タスクテーブルのフォルダIDカラムにフォルダテーブルのIDカラムへの外部キー制約を設定。

今回、一つのフォルダに複数のタスクが紐づく。

フォルダ1
|
|--- タスク1
|
|--- タスク2
|
|--- タスク3

データの不整合を防ぐために、タスクテーブルのフォルダIDには、勝手に値を入れるのではなく、フォルダテーブルのIDとして存在する値をいれなければいけない。

タスクテーブル

カラム論理名 カラム物理名 型の意味
ID id SERIAL 連番(自動採番)
フォルダID folder_id INTEGER 数値
・・・

フォルダーテーブル

カラム論理名 カラム物理名 型の意味
ID id SERIAL 連番(自動採番)
・・・

④マイグレーションの実行

php artisan migrate

⑤モデルクラスの作成

php artisan make:model Task

⑥テストデータの挿入
シーダーでtasksテーブルにデータを挿入。
tinkerでちゃんとテーブルにデータが入ったか、確認。

⑦コントローラーの追記・修正

タスク取得処理を追加。

// 選ばれたフォルダに紐づくタスクを取得する
$tasks = Task::where('folder_id', $current_folder->id)->get();

Laravel が提供するクエリビルダの機能を使用。
SQL を書かなくても PHP 風な記述でデータ操作を表現できる。
SQL は裏側で生成されデータベースに発行。
get メソッドを忘れがちなので気をつける。

return view('tasks/index', [
    'folders' => $folders,
    'current_folder_id' => $current_folder->id,
    'tasks' => $tasks,
]);

コントローラーからtaskの情報をとれるようになったので、テンプレート(ビュー)にtaskの情報を渡すように追記。

⑧テンプレートの作成

コントローラーからtaskの情報を受け取ったので、一覧画面に「resources/views/tasks/index.blade.php」フォルダ一覧だけでなくタスク一覧も表示するように記載を追加。

タスク追加ボタン、タスク一覧が追加されるが、現時点でタスク追加や編集はできないので、href="#"としている。

ここまででフォルダ一覧とタスク一覧の表示はできたが、状態や日付形式を見直しするためにLaravelのモデルに関する機能である「アクセサ」を用いてブラッシュアップ。

⑨Taskモデルにアクセサを追加

・・・ちょっと難しかったが現時点での理解を記載。

タスクテーブル

カラム論理名 カラム物理名 型の意味
ID id SERIAL 連番(自動採番)
フォルダID folder_id INTEGER 数値
タイトル title VARCHAR(100) 100文字までの文字列
状態 status INTEGER 数値
期限日 due_date DATE 日付
作成日 created_at TIMESTAMP 日付と時刻
更新日 updated_at TIMESTAMP 日付と時刻

アクセサとは:
ModelにgetHogeHogeAttribute()メソッドを定義することで、コントローラーやテンプレートで${{hoge_hoge}}としてDBの情報を加工して簡単に表示することができる。

<<Task.php>>
class Task extends Model
{
/**
 * 状態定義
 */
const STATUS = [
    1 => [ 'label' => '未着手' ],
    2 => [ 'label' => '着手中' ],
    3 => [ 'label' => '完了' ],
];

/**
 * 状態のラベル
 * @return string
 */
public function getStatusLabelAttribute()
{
    // 状態値
    $status = $this->attributes['status'];


    // 定義されていなければ空文字を返す
    if (!isset(self::STATUS[$status])) {
        return '';
    }

    return self::STATUS[$status]['label'];
    }
}

以下でTasksテーブルのstatusカラムを取得(数値1~3が取れる想定)。

$status = $this->attributes['status'];

取得したstatusの値が数値1~3でない場合、空文字を返す。

    // 定義されていなければ空文字を返す
    if (!isset(self::STATUS[$status])) {
        return '';
    }

取得したstatusの値が数値1~3の場合、'未着手'/'着手中'/'完了'を返却する。

    return self::STATUS[$status]['label'];
    }

Modelにて上記の設定ができたら、コントローラーやテンプレートにて、'未着手'/'着手中'/'完了'を取得できる。
Modelで定義した関数がgetStatusLabelAttribute()だったので、コントローラーやテンプレートで取得する際は、以下のようにする。

    <span class="label">{{ $task->status_label }}</span>

これで、状態を数値でなく'未着手'/'着手中'/'完了'で表示できるようになった。

ちなみに、この「self::」とはなんだろうか??「self::」は自分のクラスを表しthisは自分のインスタンスを表す。静的なプロパティにアクセスする際は、「self::」を使用し、動的なプロパティやメソッドにアクセスする際は、thisを使用する。

続いて、状態に応じて色を付ける。
アクセサとBootstrapをうまく活用していてすごいと思った。

上記の通り、Bootstrapでclassに定義することで、色をつけることができる。

/**
 * 状態定義
 */
const STATUS = [
    1 => [ 'label' => '未着手', 'class' => 'label-danger' ],
    2 => [ 'label' => '着手中', 'class' => 'label-info' ],
    3 => [ 'label' => '完了', 'class' => '' ],
];

/**
 * 状態を文字で表示する
 * @return string
 */
public function getStatusLabelAttribute()
{
    // 状態値
    $status = $this->attributes['status'];

    // 定義されていなければ空文字を返す
    if (!isset(self::STATUS[$status])) {
        return '';
    }

    return self::STATUS[$status]['label'];
}

 /**
 * 状態に色を付ける
 * @return string
 */
public function getStatusClassAttribute()
{
    // 状態値
    $status = $this->attributes['status'];

    // 定義されていなければ空文字を返す
    if (!isset(self::STATUS[$status])) {
        return '';
    }

    return self::STATUS[$status]['class'];
}

STATUS定義にBootstrapを踏まえたclass定義を追加し、ステータスカラムに応じたclassを返すメソッドを追加。
テンプレート側で以下の通り定義することで、色づけすることができる。

<span class="label {{ $task->status_class }}">{{ $task->status_label }}</span>

⑩モデルクラスにおけるリレーション

タスクコントローラーではタスクの一覧を以下のコードで取得した。

$tasks = Tasks::where('folder_id', $current_folder->id)->get();

ここで紹介する機能を使うとこのように書き直すことができる。(めっちゃ便利・・・!)

$tasks = $current_folder->tasks()->get();

上でも記載の通り、今回、一つのフォルダに複数のタスクが紐づく。
これを踏まえて、Folderクラスに以下の記載を加える。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Folder extends Model
{
    public function tasks()
    {
        return $this->hasMany('App\Task');
    }
}

実際に、タスクコントローラーの記載を以下のように修正する。

// 選ばれたフォルダに紐づくタスクを取得する
$tasks = Task::where('folder_id', $current_folder->id)->get();

長くなったので、(4)までで一旦、区切る。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?