Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って初めたブログ

(Laravel第2回目)MVCモデルを使った一通りの流れを理解した話

今回はMVCモデルを使った一通りの流れを学んだので、その復習(アウトプット)をしたいと思います。 参考にしたサイトは以下。

www.hypertextcandy.com

このサイトは@kuriharaさんに教えていただきました。
LaravelでToDoリストの作り方を非常に丁寧なドキュメントで書かれているサイトです。 とても分かりやすい。。。

このようなサイトを教えていただき、@kuriharaさんありがとうございますm( )m
今回は上記サイトの(4)までをやってみたので、ここまでを振り返りたいと思います。

(4)の作成時点

フォルダ毎にToDoリストがある感じです。

f:id:special-moucom:20190709233215p:plain

LaravelでのMVCの流れ

前回、MVCのデータの流れは、Controller→Model→Viewの順になると学びました。 それをLaravelで表現すると以下のようになります。

f:id:special-moucom:20190709233353p:plain

ControllerとViewの背面にRoutesが入ります。 このRoutesを使って、HTTPリクエストを特定のControllerへ渡したり、直接Viewを呼び出したりすることができます。
Routesをコードで書くと以下の通り。

■ Routes
// HTTPリクエストをTaskControllerへ渡す
// ->name('tasks.index')は、このURLの名前
Route::get('/folders/{id}/tasks', 'TaskController@index')->name('tasks.index');

// 直接Viewを呼び出す
Route::get('/', function () {
    return view('welcome');
});

上記のRouteのgetは、以下のTaskControllerのindexを呼び出しています。

■ TaskController
namespace App\Http\Controllers;

use App\Folder;
use App\Task;

class TaskController extends Controller
{
    public function index(int $id)
    {
        // ① (DB)Folderテーブルから全件取得
        $folders = Folder::all();

        // ② HTTPリクエストから取得した$idをキーに(DB)Folderテーブルから検索
        $current_folder = Folder::find($id);
        
        // ③ (DB)Taskテーブルから②と一致するデータを取得
        $tasks = Task::where('folder_id', $current_folder->id)->get();

        // ④ ①と③の結果と$idをViewへ渡す
        return view('tasks/index', [
            'folders' => $folders,
            'current_folder_id' => $current_folder->id,
            'tasks' => $tasks,
        ]);
    }
}

①〜③で、DBへのアクセスと④でデータをViewへ渡しているのがわかります。 Modelを呼び出してないように見えますが、「Folder::all」「Task::where」でちゃんと呼び出しています。

■ Model(Task)
namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    const STATUS = [
        1 => [ 'label' => '未着手', 'class' => 'label-danger' ],
        2 => [ 'label' => '着手中', 'class' => 'label-info' ],
        3 => [ 'label' => '完了', 'class' => '' ],
    ];

    // アクセサ
    public function getStatusLabelAttribute()
    {

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

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

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

    public function getStatusClassAttribute()
    {
        $status = $this->attributes['status'];

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

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

Modelを見て、Folder::all(allメソッド)Task::where(whereメソッド)が見つからない事に気づくと思います。
これは実はModel(Task)の継承先のIlluminate\Database\Eloquent\Modelから呼んでいるIlluminate\Database\Query\Builderのallとwhereメソッドを呼んでいます。(ふ、深い・・・)

つまり、Modelに処理を何も書かなくても、Modelを呼ぶだけでQueryBuilder(allとかwhereとかDB検索に使用できるメソッド)が使用できます。これは便利!
Modelのアクセサの説明はViewでします。

■ View一部抜粋
<div class="list-group">
    @foreach($folders as $folder)
        <a href="{{ route('tasks.index', ['id' => $folder->id]) }}" 
        class="list-group-item {{ $current_folder_id === $folder->id ? 'active' : '' }}">
        {{ $folder->title }}
        </a>
    @endforeach
</div>


@foreach($tasks as $task)
    <tr>
    <td>{{ $task->title }}</td>
    <td>
    <span class="label {{ $task->status_class }}">{{ $task->status_label }}</span>
    </td>
    <td>{{ $task->due_date }}</td>
    <td><a href="#">編集</a></td>
    </tr>
@endforeach

データを表示するところのViewです。
Laravelは、Bladeと呼ばれるテンプレートエンジンを採用しています。@foreachでforeachが使えたり、phpを{{ hoge }}で出力できたり等、とても便利です。

基本的にControllerを使って取得したデータを表示するだけですが、ポイントが2つあります。

  • URLのPathはRoutesで定義した名前を使う!
  • アクセサ

URLのPathはRoutesで定義した名前を使う!

本来、href=の後にはURLを指定するのですが、Routesでnameを指定しておくと、以下のように書くことができます。

<a href="{{ route('tasks.index', ['id' => $folder->id]) }}"

こうすることで、URLを誤って書くことが少なくなります。また、名前に誤りがあれば、PHP側でエラーがでます。

アクセサ

以下を見てください。

{{ $task->status_label }}

ControllerからViewへデータを渡す時に、$taskを渡しました。 $taskはDBから取得したデータなのですが、実はDBには「status_class」や「status_label」といったデータは入っていません。 これはModelにあるアクセサ「getStatusClassAttribute」と「getStatusLabelAttribute」を指しています。

アクセサメソッドはキャメルケース(文字の区切りが大文字)ですが、プロパティとして参照するときは(getとAttributeを除いた)スネークケース(文字の区切りがアンダースコア)で参照することができます。
DBから取得したデータを加工したいときに使えるので便利っ!!

最後に

LaravelのMVCモデルをつかって、一通りの流れを学びました。
Rails以来、久しぶりにモダンなフレームワークに触れたのですが、やっぱりバックエンドって楽しいですよね。
自分自身の理解も兼ねて引き続きアウトプットしていきたいと思います。( = = )ノ

(Laravel第1回目)Laravel勉強はじめるぞっ

お久しぶりです。 ちょっとブログの更新頻度が落ちてしまってたので、申しわけありません。 また、更新頻度を上げれる様に努力したいと思います。

さて、近況ですが、最近Laravelの勉強を始めました。 これがなかなか難しく、あまり理解が進んでいないのですが、自身への理解を深めるため、ブログにアウトプットしていきたいと思います。

というわけで、Laravelアウトプットの第1回目です。

Laravelとは?

PHP業界で最近流行りのフレームワーク
学習コストが低く、PHPのコードを綺麗に書くことでき、加えて豊富なライブラリ揃っているのが流行りの理由。また、早くからVue.jsに対応しているのも特徴の1つです。

まぁ、私自身Laravelを学び始めたばかりなので、これらの特徴にあまり体感できていないのですが……(- o - ;;)
1つ言える事は、RubyRailsフレームワークに非常に近いと感じました。学習コストが低いという点では、Rails触ったことがある人ならとっつき易いのかなぁと思います。(ただ、そもそも言語が違うのでRubyPHP両方を知っている人なら...という事になりますね)

MVCモデルとADRモデル

Railsフレームワーク同様、LaravelもMVCモデルを採用しています。
加えて、LaravelはMVCモデルから派生したADRモデルも採用しています。
2つのモデルに対応できるフレームワークになっているんですね。

ここのところ、よく理解できなかったので少し掘り下げたいと思います。

MVCモデルとは?

MVCモデルは、Model View Controllerの略で、HTTPリクエストの受信から何かしらレスポンスを返すまでのデータの流れをModel、View、Controllerの3つの役割に分けて管理していこうという開発モデルになります。

各々の役割としては以下の通り。

  • Controller ・・・ リクエストに応じて処理を振り分ける役割
  • Model ・・・ ビジネスロジックを処理する役割
  • View ・・・ リクエストの処理結果を返す役割

図で表すと以下のようなイメージ。

f:id:special-moucom:20190701233432p:plain

ADRモデル

ADRモデルは、MVCモデルから派生したモデルです。
Action Domain Responderの略で、HTTPリクエストの受信から何かしらレスポンスを返すまでのデータの流れをAction、Domain、Responderの3つの役割に分けて管理していこうという開発モデルになります。

これら3つの役割は、実はMVCモデルと変わりありません。

  • Action(≒Controller) ・・・ リクエストに応じて処理を振り分ける役割
  • Domain(≒Model) ・・・ ビジネスロジックを処理する役割
  • Responder(≒View) ・・・ リクエストの処理結果を返す役割

しかし、MVCモデルの派生モデルだけあって、考え方が違います。
MVCモデルは画面設計ベース(画面に対して、どのようなレスポンスを返そう?)になっていますが、ADRモデルはURI設計ベース(このURIに対して、どのようなレスポンスを返そう?)になっています。

最近のバックエンド開発では、画面に対してのレスポンスだけではなく、RESTfullなAPIレスポンスも増えてきました。APIは、URIに応じて受け渡すデータを変える必要があるため、ADRという考え方ができたのだと(私が勝手に)推測しています。

図で表すと以下のようなイメージ。MVCと変わりありませんよね(= =;;)

f:id:special-moucom:20190701233442p:plain

感想

私は過去にRailsチュートリアルを途中までやっていました。転職先が決まった後から、ずっと放置してますが・・・(転職先ではRubyはやらないので(TT))
その時に、MVCモデルについては知っていましたが、ADRモデルについては今回のLaravelで初めて知りました。
その興味に惹かれて、ADRモデルからLaravelの勉強を始めましたが、なかなか理解が追いつかず・・・もう少し理解することができたら深掘りして、またブログにアウトプットしていきたいと思います。

Python3エンジニア認定基礎試験に合格した話

Python3エンジニア認定基礎試験とは?

「一般社団法人Pythonエンジニア育成推進協会」が実施している民間試験。
通年を通して試験が行われており、全国のオデッセイコミュニケーションズCBTテストセンターで受験が可能です。なお、受験料は1万円(税抜き)。

一般社団法人Pythonエンジニア育成推進協会は、ビッグデータPython市場の隆盛に備えて設立された団体だそうです。

www.pythonic-exam.com

なぜ受験を考えたのか?

社内で以下記事の画像(取得したい資格)について話していた時である。

人気沸騰のIT資格、取得したい資格ランキング | 日経 xTECH(クロステック)

AWSGCP等のクラウド系の資格に人気があり、注目される中、真ん中にPythonという特定の言語の資格がえらい人気・・・
そこで、上司が・・・

上司「KodakAWSの資格(SAA)持ってるんだし、このPythonの資格受けてみれば?」

Kodak「うーん・・・(しばらく考える)」
(調べてみると合格率も高そうだし、今期は私自身プログラミング力を上げることを目標にしていたし、受けてみるか)

Kodak「受けてみます!」

と、あまり深く考えずに、とりあえず受けてみることにしました。

合格までの道のり

本試験の問題は、オライリー本の「Pythonチュートリアル」から出題されます。

Pythonチュートリアル 第3版

Pythonチュートリアル 第3版

が・・・この「Pythonチュートリアル」は一般公開されているので、必ずしも購入する必要はありません。

docs.python.org

私も書籍は購入せずに、一般公開されている情報だけで、合格できました。

1. 決めること

こういった資格の勉強は、ダラダラやっても頭に入らないので「まず、2週間後に受験しよう」ということを決めました。

2. あとは時間の許す限り写経

勉強時間は個人差が出てくると思いますが、Pythonチュートリアルを2周(写経あり)しました。

3. 模擬試験に挑戦

以下で模擬試験を受けることができます。 7〜8割とれてれば大丈夫(自信に繋がる)でしょう。

DIVE INTO EXAM

個人的重要ポイント

1. try...except(catch)...else!?...finally

例外処理にelseを入れることができます。
elseは、tryでエラーがでなかった場合にのみ処理が実行されます。
他の言語を見ても、tryにelseを入れた処理を見たことがなかったので、重要ポイントに入れました。

>>> try:
...     num = 5 * 5
... except Error:
...     print('Error')
... else:
...     print(num)
... finally:
...     print('hoge')
...
25
hoge
>>>

2. for...else!?

今度は、forにelseを入れることができます。
forでbreakされなかった場合にのみ処理が実行されます。
こちらも他の言語ではなかなか見ないですよね。

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

3. インタプリタ、_

ここは重要です。忘れやすいし、知らない人が多いと思います。
インタプリタでのみの仕様ですが、'_'は、最後に実行された結果が格納されています。

>>> fuga = 10 * 10
>>> fuga
100
>>> _
100

感想

書籍を購入する必要がなかったので、かかったのは時間と受験料(1万)だけ。
これだけでプログラミングの勉強ができて、合格すれば資格が貰える・・・こんなにコスパの良い資格は他にないと思います。

Pythonを勉強したい方は、まずはこの資格獲得を目標にして勉強するのが良いかもしれません。
テストやお金が掛かる(受験料)と本気で勉強しようと思えるので、良いきっかけになると思います。

ポートフォリオサイトを作った話

年初に言っていた自身のポートフォリオサイトを作成する目標が、やっと達成できました。

www.tama-kodak.com

本当なら3,4ヵ月くらいで作るつもりでしたが、私自身の知識不足と病気(胃腸炎腸炎・風邪など)でなかなか前に進まず・・・苦労しました(涙
コンテンツは少ないですが、見てあげてください。m(_ _)m

使用技術について

SPAです。フロント側はVue.jsで作って、AWSのS3にホスティングさせています。

工夫した箇所

1. ダークモードを取り入れた。
macOS Mojaveから導入されたダークモード(時間帯によって画面の表示スタイルが変わるモードのこと)。 これをWebサイトでも実現できたらおもしろいんじゃないかなぁと思い、自身のポートフォリオサイトに取り入れてみることにしました。

f:id:special-moucom:20190525230140p:plain

このホワイトモードとダークモードの切り替えは、AWSのLambdaで行っています。
S3にモードを切り替え用のJSONファイルを置いておいて、そのモードの切り替えをLambdaでしています。

2. デザイン力の無さはライブラリでカバー!
最初は地道にデザインを考えていたのですが、自身のデザイン力の無さに挫折。
結局、BootstrapVueやSnowfといったライブラリを取り入れることにしました。しかし、ただライブラリを使うのでは面白みがないと感じたので、アニメーションを入れてみました。

f:id:special-moucom:20190525230146p:plain

3. デプロイの自動化
毎回、S3にビルドしたファイルを置くのが面倒に感じたので自動化しました。CodePipelineを使ってGitHubと連携させて、Pushしたら自動でビルド、デプロイさせるようにしました。

AWS全体図

全体としては、以下のような作りになりました。

f:id:special-moucom:20190525225934p:plain

API用のJSONファイルのホスティング先をどうするか悩みましたが、CloudFrontのマルチオリジンBehavior機能を使いました。

学んだこと

  • 自分はCSSが苦手だった。デザイン力もなかった。
    実際に作ってみて、自分はCSSが苦手であること。デザイン力がない事を実感しました。
    とくにアニメーションやトランジションの使い方がわからず、すごく悩みました。(色々な方に聞いたと思いますが、改めて「ありがとうございました。」)
    次回作に向けて、CSSに対する苦手意識をなくすこと。ライブラリの使用を最初から検討すること。など、新たな目標や考え方が身についたので、活かしたいと思います。

  • Vue.jsがまだまだ 実際に物を作ってみると、自分のVue.jsに対する知識がまだまだであることを実感させられました。
    使えると便利なので、もっと学んでいきたいと思います。

  • 永遠のLv2
    ポートフォリオサイト作成時に自身のスキルの棚卸しをしたのですが、改めて自分の中途半端さに気が付きました。(得意分野が無い・・・)
    この永遠のLv2から脱出するのも1つの目標となりそうですorz

f:id:special-moucom:20190525230719p:plain

最後に

今回、自身のポートフォリオサイトを作ってみて、色々と勉強になりました。(自身のスキルの中途半端さにも気づけましたorz)
技術的なことは、なにかあればQiitaの方にも書いてみたいと思います。

GW中に「リーダブルコード」を読み直した話

GW・・・終わってしまいましたね。
今回は10日間の長い連休でしたが、私自身は子供の相手をしたり、腸炎になったり・・・と、なかなかゆっくりできなかった連休でした(涙
そんな中、「リーダブルコード」を読み直したので、その感想を書いていきます。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコードとは?

「良いプログラムコードとは、他人が読みやすいコードである。」という事を前提に置いて「では、他人が読みやすいコードを書くにはどうすれば良いのか?」という疑問に応えてくれる本です。
この前提は正しく、読みやすいコードはプログラムの品質(バグの早期発見)に繋がります。
変数の名前から処理の方法まで、どうすれば分かりやすく、見やすいコードを書けるようになるのかを1つずつ例を出しながら説明してくれています。本書の内容についても、オライリー本では珍しく読みやすくなっています。

なぜ読み直そうと考えたのか?

  • その1. 転職後(コードを書くようになってから)読み返してみたかった
    以前「リーダブルコード」読んだのは転職前(コードを書いていない時代)でした。なので、転職後(コードを書くようになってから)に読み返すと、また違った見方で読めるのではないかと思いました。

  • その2. 自分のコードに自身が持てない
    名前が大事だ!コメントは完結に!等、以前読んだ時の内容は少し覚えていました。しかし、曖昧に記憶している部分が多く、すでに自分のコードに自身が持てなくなっていたので、自身のコードと見返しながら読みたいと思った。

読み直して感じたこと

  • 「リーダブルコード」の内容こそが、リファクタリングの観点だと気づいた
    以前「テスト駆動開発」の本を読みました。(残念ながら、いまだにTDDの実践投入ができていない状態ですが・・・) kodak.hatenablog.com TDDにおける「リファクタリング」という部分が、まさに「リーダブルコード」に該当するところでした。
    本書でもテストコードの部分に触れており、テストコードの読みやすさについて書かれている部分がありました。TDDを知ってから読み返したことで、本書を「リファクタリング」という見方で読むことができました。

  • 本書を活かすところが全然ないと感じる =「気づいていない」だけでは?
    この記述は、付録にありました。私自身、これはすごく感じます・・・が、きっと本書の通り「気づいていない」だけなんでしょうね。
    本書を読んだ後で、自分の書いたコードが直ぐに本書の通りになるか?といえば、それは「NO」です。付録にも書かれていますが、「継続すること」が大事だそうです。と、読み返す事で、色々と気づいていない事に気づけました。

最後に

「リーダブルコード」は、やはり良い本だと改めて再認識しました。
読み直しを行う事で、改めて色々と再認識した部分があり、非常に勉強になりました。また、本書は薄い本なので、さらっと読み返すには丁度いいです。 また定期的に読み返したいと思います。