AdonisJsとMySQLを使用して感動的な見積もりアプリケーションを構築する方法

提供:Dev Guides
移動先:案内検索

著者は、 Write forDOnationsプログラムの一環として寄付を受け取るためにTechEducationFundを選択しました。

序章

AdonisJs は、すべての主要なオペレーティングシステムで実行されるプレーンなJavaScriptで記述されたNode.jsWebフレームワークです。 人気のあるMVC(モデル-ビュー-コントローラー)デザインパターンを使用し、サーバー側のWebアプリケーションを作成するための安定したエコシステムを提供します。 フレームワークは、シームレスな認証、SQL ORM(オブジェクトリレーショナルマッピング)、移行、およびデータベースシードを備えています。 AdonisJsは、PHPWebアプリケーションフレームワークLaravel と同様のアーキテクチャを備えており、同じフォルダー構造といくつかの共有セットアップの概念が含まれています。

デフォルトでは、AdonisJsは直感的に使用できるように設計されたEdgeテンプレートエンジンを使用します。 Laravelと同様に、AdonisJsには、アプリケーションのモデルとデータベース間の通信用のインターフェイスとして機能するLucidと呼ばれるORMが付属しています。 AdonisJsを使用すると、開発者はフルスタックアプリケーションを構築できます。このアプリケーションでは、バックエンドサーバーがビジネスロジックの適用、ルーティング、およびアプリケーションのすべてのページのレンダリングを担当します。 コントローラからJSON応答を返すWebサービスAPIを作成することもできます。 これらのWebサービスは、 Vue.jsReactAnglerなどのフロントエンドフレームワークを使用して利用できます。

このチュートリアルでは、CLIを使用してAdonisJsでアプリケーションを構築します。 アプリケーション内にルート、コントローラー、モデル、およびビューを作成し、フォームの検証を実行します。 このチュートリアルの例は、ユーザーがサインアップしてログインして感動的な見積もりを作成できる、感動的な見積もりアプリケーションです。 このデモアプリケーションは、CRUD(作成、読み取り、更新、および削除)操作を実行する機会を提供します。

前提条件

このガイドを開始する前に、次のものが必要です。

  • Node.js (少なくともv8)および npm (少なくともv3.0)のローカルインストール。 Node.jsは、ブラウザの外部でコードを実行できるJavaScriptランタイム環境です。 npmと呼ばれるパッケージマネージャーがプリインストールされており、パッケージをインストールおよび更新できます。 これらをmacOSまたはUbuntu18.04にインストールするには、Node.jsをインストールしてmacOSにローカル開発環境を作成する方法またはのPPAセクションを使用したインストールの手順に従います。 Ubuntu18.04にNode.jsをインストールする方法。
  • MySQLがマシンにインストールされています。 こちらの手順に従って、選択したオペレーティングシステム用にダウンロードしてインストールします。 MySQLを正常にインストールするには、HomebrewMacに使用するか、Ubuntu18.04のチュートリアルMySQLをUbuntu18.04にインストールする方法に従ってインストールします。
  • JavaScriptの基本的な理解; JavaScriptでコーディングする方法シリーズをご覧ください。
  • Visual Studio CodeAtomSublimeTextなどのテキストエディターがインストールされています。

注:このチュートリアルでは、開発にmacOSマシンを使用します。 別のオペレーティングシステムを使用している場合は、最初の手順でnpmコマンドにsudoを使用する必要がある場合があります。


ステップ1—AdonisCLIのインストール

このセクションでは、 AdonisCLIとそれに必要なすべてのパッケージをローカルマシンにインストールします。 CLIを使用すると、新しいAdonisJsプロジェクトの足場を作成したり、アプリケーションのコントローラー、ミドルウェア、モデルの定型文を作成および生成したりできます。 プロジェクトのデータベースも作成します。

次のコマンドを実行して、npmを介してAdonisJsCLIをマシンにグローバルにインストールします。

npm i -g @adonisjs/cli

インストールプロセスが完了したら、ターミナルで次のコマンドを入力して、AdonisJsのインストールを確認し、現在のバージョンを表示します。

adonis --version

AdonisJsの現在のバージョンを示す出力が表示されます。

Output4.1.0

AdonisJs CLIが正常にインストールされると、adonisコマンドにアクセスして使用できるようになり、AdonisJsプロジェクトの新規インストールを作成し、プロジェクトを管理し、コントローラーやモデルなどの関連ファイルを生成できます。 。

これで、次のようにadonisコマンドを使用して、新しいAdonisJsプロジェクトの作成に進むことができます。

adonis new adonis-quotes-app

上記のコマンドは、adonis-quotes-appという名前のアプリケーションを、関連するAdonisJsMVC構造を持つローカルプロジェクトディレクトリ内の同じ名前の新しいディレクトリに作成します。

新しいアプリケーションフォルダに移動します。

cd adonis-quotes-app

次に、以下を実行してアプリケーションを起動します。

adonis serve --dev

これにより、アプリケーションのルート.envファイル内で指定されているように、デフォルトのポート3333で開発サーバーが起動します。 http:// localhost:3333 に移動して、AdonisJsのウェルカムページを表示します。

これで、データベースのセットアップが完了します。 ここでは、 mysqlドライバーをインストールして、Node.jsアプリケーションからnpmを介してMySQLサーバーに接続します。 開始するには、アプリケーションが現在実行されているターミナルに戻り、CTRL + Cでプロセスを停止し、次のコマンドを実行します。

npm i mysql

このアプリケーションのMySQLNode.jsドライバーが正常にインストールされたので、アプリケーションデータベースを作成し、それに適切な接続を設定する必要があります。

前提条件のチュートリアルからインストールした最新バージョンのMySQLは、caching_sha2_passwordという名前のデフォルトの認証プラグインを使用します。 これは現在、MySQLのNode.jsドライバーではサポートされていません。 アプリケーションからのデータベース接続の問題を回避するには、新しいMySQLユーザーを作成し、現在サポートされている認証プラグインmysql_native_passwordを使用する必要があります。

まず、rootアカウントを使用してMySQLクライアントにアクセスします。

mysql -u root -p

MySQLのインストール中に設定したrootアカウントのパスワードを入力するように求められます。

次に、mysql_native_passwordプラグインを使用してユーザーとパスワードを作成します。

CREATE USER 'sammy'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

次の出力が表示されます。

OutputQuery OK, 0 rows affected (0.02 sec)

次に、次のコマンドを使用してアプリケーションのデータベースを作成します。

CREATE DATABASE adonis;

次の出力が表示されます。

OutputQuery OK, 1 row affected (0.03 sec)

これで、このアプリケーションのデータベースが正常に作成されました。

次に、新しいMySQLユーザーに対して作成されたデータベースへのアクセスを有効にします。 次のコマンドを実行して、データベース内のユーザーにすべての特権を付与します。

GRANT ALL PRIVILEGES ON adonis.* TO 'sammy'@'localhost';

次のコマンドを実行して付与テーブルを再ロードし、行った変更を適用します。

FLUSH PRIVILEGES;

次の出力が表示されます。

OutputQuery OK, 0 rows affected (0.00 sec)

次のコマンドでMySQLクライアントを終了します。

quit;

これで、AdonisJs CLIが正常にインストールされ、新しいAdonisJsプロジェクトが作成され、npmを介してmysqlがインストールされました。 また、このアプリケーションのデータベースを作成し、適切な権限を持つMySQLユーザーを設定しました。 これはアプリケーションの基本的な設定であり、次のセクションでは、アプリケーションに必要なビューの作成を開始します。

ステップ2—エッジテンプレートエンジンを使用する

AdonisJsには、Edgeと呼ばれる独自のテンプレートエンジンが付属しています。 これにより、再利用可能なHTMLテンプレートを作成し、最小限のコードでフロントエンドロジックをアプリケーションに導入できます。 Edgeは、JavaScript開発者に、コンポーネントベースのレイアウトを構築し、条件を記述し、反復を使用し、ロジックを保持するためのビューレイヤーを作成するアプリケーションを開発する際のツールを提供します。 すべてのテンプレートファイルは.edge拡張子で終わり、resources/viewsディレクトリに保存されます。

以下は、アプリケーションが正しく機能するために必要なビューです。

  • マスターレイアウト:Edgeを使用すると、CSS、一般的なJavaScriptファイル、jQuery、およびアプリケーション全体で同じままであるユーザーインターフェイスの一般的な部分(ナビゲーションなど)を含むページを作成できます。バー、ロゴ、ヘッダーなど。 マスターレイアウトページを確立すると、アプリケーションの他のビュー(ページ)がそれを継承します。
  • インデックスビュー:このページは、マスターレイアウトを使用して共通ファイルを継承し、アプリケーションのホームページのコンテンツもレンダリングします。
  • ログインページ:このページもマスターレイアウトを使用し、ユーザーがログインするためのユーザー名とパスワードの両方の入力フィールドを含むフォームをレンダリングします。
  • 登録ページ:ここで、ユーザーは登録するためのフォームを表示し、詳細をデータベースに保持します。
  • 見積もりページの作成:ユーザーはこのページを使用して感動的な見積もりを作成します。
  • 見積もりページの編集:ユーザーはこのページを使用して見積もりを編集します。
  • 見積もりページの表示:ユーザーはこのページを使用して特定の見積もりを表示します。

まず、adonisコマンドを使用して、次のコマンドを実行してマスターレイアウトページを作成します。

adonis make:view layouts/master

次のような出力が表示されます。

Output✔ create  resources/views/layouts/master.edge

このコマンドは、resources/views/layoutsフォルダーにmaster.edgeファイルを自動的に作成します。 新しいファイルを開きます。

nano resources/views/layouts/master.edge

その中に次のコードを追加します。

/resources/views/layouts/master.edge

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>adonis-quotes-app</title>
    {{ style('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css') }}
    {{ style('style') }}
    {{ script('https://code.jquery.com/jquery-3.3.1.slim.min.js') }}
</head>
<body>
    <div class="container-fliud">
        @include('navbar')
        @!section('content')
    </div>
    {{ script('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js') }}

</body>
</html>

このファイルには、 Bootstrap CSS、Bootstrap JavaScript、、およびjQueryのCDNファイルが含まれています。 style.cssという名前のグローバルCSSファイル名を追加し、div内にnavbarという名前のpartialファイルを含めます。 navfooterなど、アプリケーションの複数のページで必要なHTMLコードのフラグメントを再利用するには、パーシャルを組み込むことができます。 これらは繰り返されるコードを含む小さなファイルであり、発生するすべてのインスタンスではなく、これらの要素のコードを1か所ですばやく更新できます。 navbarには、LoginおよびRegisterボタンのマークアップ、ロゴ、およびホームリンクが含まれています。

これにより、このアプリケーション用に作成される後続のすべてのページでマスターレイアウトを拡張し、コンテンツを最初から書き直すことなくnavbarをレンダリングできます。 このnavbarファイルは、チュートリアルの後半で作成します。

最後に、セクションタグ@!section()を定義して、他のページのコンテンツを含め、マスターレイアウトでレンダリングします。 これが期待どおりに機能するためには、マスターレイアウトを拡張するすべての新しいページで、同じ名前(@section(``'``content``'``)など)のセクションタグも定義する必要があります。

編集が終了したら、ファイルを保存して終了します。

次に、adonisコマンドを使用して、ナビゲーションバーを作成します。

adonis make:view navbar

次のような出力が表示されます。

Output✔ create  resources/views/navbar.edge

新しく作成したファイルを開きます。

nano resources/views/navbar.edge

次に、次のコードを追加します。

/resources/views/navbar.edge

<nav class="navbar navbar-expand-lg navbar-dark text-white">
    <a class="navbar-brand" >LOGO</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
            <li class="nav-item active ">
                <a class="btn text-white" href="/">Home</a>
            </li>
        </ul>
    </div>
    <div class="navbar-right" id="navbarNav">
        @loggedIn
            <ul class="navbar-nav">
                    <li>
                        <div class="text-right">
                             <a href="{{route('create.quote')}}" class="btn btn-outline-primary">Create Quote</a>
                        </div>
                    </li>

                <li class="nav-item dropdown">
                    <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                       {{ auth.user.username}}
                    </a>
                    <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                        <form method="POST" action="{{route('logout')}}">
                            {{ csrfField() }}
                              <button  type="submit" class="dropdown-item" href="">logout</button>
                        </form>
                    </div>
                </li>
            </ul>
        @else
            <ul class="navbar-nav">
                <li class="nav-item active pr-2">
                    <a href="{{route('login.create')}}" class="btn btn-outline-danger">
                      login
                    </a>
                </li>
                <li class="nav-item active pr-2">
                    <a href="{{route('register.create')}}" class="btn btn-outline-primary">
                        Register
                    </a>
                </li>
            </ul>
        @endloggedIn
    </div>
</nav>

ホームページへのリンクと登録およびログインするためのボタンを定義することに加えて、@loggedInタグを追加します。 これが適切な場所にあると、認証されたユーザーの周りに条件付きステートメントを記述し、必要に応じて適切なコンテンツを表示できます。 認証されたユーザーの場合、アプリケーションはユーザー名と新しい見積もりを作成するためのボタンを表示します。 ユーザーがログインしていない場合、アプリケーションはログインまたは登録するためのボタンを表示します。 このページは、このアプリケーションのマスターレイアウトで以前に使用されていたように、すべてのページに部分的に含まれます。

ファイルを保存して終了します。

次に、アプリケーションのホームページに使用するインデックスページを作成します。 ユーザーが書いたすべての感動的な引用のリストをレンダリングして表示します。

adonis make:view index

次のような出力が表示されます。

Output✔ create  resources/views/index.edge

ここで作成したファイルはresources/views/index.edgeにあります。 ファイルを開きます。

nano resources/views/index.edge

次に、次のコードを追加します。

/resources/views/index.edge

@layout('layouts/master')
@section('content')

<div class="container">
    <div class="text-center">
        @if(flashMessage('successmessage'))
            <span class="alert alert-success p-1">{{ flashMessage('successmessage') }}</span>
        @endif
    </div>
    <div class="row">
        @each(quote in quotes)
            <div class="col-md-4 mb-4 quote-wrapper">
                <a href="/view-quote/{{quote.id}}" class="w-100">
                    <div class="card shadow-lg bg-dark text-white">
                        <div class="card-body">
                            <blockquote class="blockquote mb-0">
                                <p>{{quote.body}}</p>
                                <footer class="blockquote-footer">
                                    <cite title="Source Title"> {{quote.username}}</cite>
                                </footer>
                            </blockquote>
                            @if(auth.user.id == quote.user_id)
                              <div>
                                <a  href="/edit-quote/{{quote.id}}" class="btn btn-primary">edit</a>
                                <a href="/delete-quote/{{quote.id}}" class="btn btn-danger">delete</a>
                              </div>
                            @endif
                        </div>
                    </div>
                </a>
            </div>
        @else
         <div class="col-md-12 empty-quote text-center">
                <p>No inspirational quote has been created</p>
         </div>
        @endeach
    </div>
</div>
@endsection

ここでは、このビューを拡張してmasterレイアウトを使用することを示します。 このページは、masterレイアウトに含まれるすべてのライブラリ、スタイルシート、およびnavbarにアクセスできるようになりました。 次に、組み込みの@eachタグを使用して、quotesの配列を反復処理します。 quotes配列は、このチュートリアルの後半で作成するQuoteControllerからこのビューに渡されます。 引用符がない場合は、適切なメッセージが表示されます。

このファイルを保存して終了します。

ここで、ログインページを作成するには、ターミナルから次のコマンドを実行します。

adonis make:view auth/login

次のような出力が表示されます。

Output✔ create  resources/views/auth/login.edge

これにより、resources/views内にauthフォルダーが自動的に作成され、その中にlogin.edgeファイルも作成されます。 login.edgeファイルを開きます。

nano resources/views/auth/login.edge

次のコンテンツを追加します。

/resources/views/auth/login.edge

@layout('layouts/master')
@section('content')
  <div class="container">
    <div class="row">
      <div class="col-md-4 shadow bg-white mt-5 rounded offset-md-4">
        <form method="POST" action="{{route('login.store')}}">
          {{ csrfField() }}
            <div>
              @if(flashMessage('successmessage'))
                <span class="alert alert-success p-1">{{ flashMessage('successmessage') }}</span>
              @endif
            </div>
            <div class="form-group">
              <label for="email">Email address</label>
              <input type="email" class="form-control" id="email" name="email" value="{{old('email','')}}"  placeholder="Enter email">
              {{ elIf('<span class=text-danger>$self</span>', getErrorFor('email'), hasErrorFor('email')) }}
            </div>
            <div class="form-group">
              <label for="pasword">Password</label>
              <input type="password" class="form-control" id="password" name="password" value="{{old('password','')}}" placeholder="Password">
              {{ elIf('<span class=text-danger>$self</span>', getErrorFor('password'), hasErrorFor('password')) }}
            </div>

            <div class="text-center">
              <button type="submit" class="btn btn-primary">Submit</button>
            </div>
        </form>
      </div>
    </div>
  </div>
@endsection

このファイルには、登録済みユーザーが認証されて見積もりの作成を開始する前に、ユーザー名とパスワードを収集するために使用する入力要素を含むフォームが含まれています。 このページで注意すべきもう1つの重要な要素は、テンプレート:CsrfField()です。 これは、アプリケーションからPOSTPUT、およびDELETE要求を送信するときに、AdonisJがCSRFアクセストークンを渡すために使用するグローバル変数です。

これは、クロスサイトリクエストフォージェリ(CSRF)攻撃からアプリケーションを保護するために導入されました。 これは、Webサイトにアクセスするユーザーごとに一意のCSRFシークレットを生成することで機能し、ユーザーがフロントエンドからHTTPリクエストを送信すると、このシークレットに対応するトークンが生成され、リクエストとともに渡されます。 これにより、AdonisJs内でこのリクエスト用に作成されたミドルウェアが、トークンとCSRFシークレットの両方が有効であり、現在認証されているユーザーに属していることを確認できます。

終了したら、ファイルを保存して終了します。

次に、次のコマンドを使用して登録ページを作成します。

adonis make:view auth/register

次のような出力が表示されます。

Output✔ create  resources/views/auth/register.edge

resources/views/auth/register.edgeで新しく作成されたファイルを見つけて開きます。

nano resources/views/auth/register.edge

次のコードを追加します。

resources / views / auth / register.edge

@layout('layouts/master')
@section('content')
  <div class="container ">
    <div class="row">
        <div class="col-md-4  bg-white p-3 mt-5 shadow no-border rounded offset-md-4">
          <form method="POST" action="{{route('register.store')}}">
            {{ csrfField() }}
              <div class="form-group">
                <label for="name">Fullname</label>
                <input type="text" class="form-control" id="name" name="name"  value="{{old('name','')}}" placeholder="Enter Fullname">
                {{ elIf('<span class=text-danger>$self</span>', getErrorFor('name'), hasErrorFor('name')) }}
              </div>
              <div class="form-group">
                <label for="email">Email address</label>
                <input type="email" class="form-control" id="email"  name="email" value="{{old('email','')}}" placeholder="Enter email">
                {{ elIf('<span class=text-danger>$self</span>', getErrorFor('email'), hasErrorFor('email')) }}
              </div>
              <div class="form-group">
                <label for="pasword">Password</label>
                <input type="password" class="form-control" id="password" name="password" placeholder="Password">
                {{ elIf('<span class=text-danger>$self</span>', getErrorFor('password'), hasErrorFor('password')) }}
              </div>
              <div class="text-center">
                  <button type="submit" class="btn btn-primary">Submit</button>
              </div>
          </form>
        </div>
    </div>
  </div>
@endsection

ログインページにあるものと同様に、このファイルには、登録プロセス中にユーザーのnameemail、およびpasswordを収集するための入力フィールドを含むHTMLフォームが含まれています。 また、AdonisJsアプリケーションの各投稿リクエストに必要なテンプレート:CsrfField()も含まれています。

ファイルを保存して終了します。

次に、ターミナルから次のコマンドを実行して、感動的な引用を作成するための新しいファイルを生成します。

adonis make:view quotes/create-quote

次のような出力が表示されます。

Output✔ create  resources/views/quotes/create-quote.edge

resources/views/quotes/create-quote.edgeを開きます:

nano resources/views/quotes/create-quote.edge

そして、それに次のコンテンツを追加します。

/resources/views/quotes/create-quote.edge

@layout('layouts/master')
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-3"></div>
        <div class="col-md-6 shadow bg-white mt-5 rounded p-3">
            <div class="float-right">
                <a href="/" class="btn btn-outline-dark ">back</a>
            </div>
                <br>

            <div class="clear-fix"></div>
                <form method="POST" action="{{route('store.quote')}}">
                    {{ csrfField() }}
                    <div class="form-group">
                        <label for="quote">Create Quote</label>
                        <textarea type="text" rows="5"  name='body' id="body" class="form-control" id="quote" placeholder="Write an inspirational quote"></textarea>
                    </div>

                    <div class="text-center">
                        <button type="submit" class="btn btn-primary">Submit</button>
                    </div>
                </form>
            </div>
        </div>
        <div class="col-md-3"></div>
    </div>
</div>
@endsection

このページはマスターレイアウトを拡張し、テキスト領域要素を含むHTMLフォームを含みます。これにより、ユーザーは、適切なルートで投稿および処理される前に、複数の行にテキストを入力できます。

終了したら、ファイルを保存して終了します。

次に、特定の見積もりを編集するためのページを作成します。 ターミナルから次のコマンドを実行します。

adonis make:view quotes/edit-quote

次の出力が表示されます。

Output✔ create  resources/views/quotes/edit-quote.edge

次のコマンドでファイルを開きます。

nano resources/views/quotes/edit-quote.edge

次のコンテンツをresources/views/quotes/edit-quoteに追加します。

/resources/views/quotes/edit-quote.edge

@layout('layouts/master')
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-6 shadow bg-white rounded p-3 offset-md-3">
            <div class="float-right">
                <a href="/" class="btn btn-outline-dark ">back</a>
            </div>
            <br>

            <div class="clear-fix"></div>
            <form method="POST" action="/update-quote/{{quote.id}}">
                {{ csrfField() }}
                <div class="form-group">
                    <label for="pasword">Edit Quote</label>
                    <textarea type="text" rows="5"  name='body' id="body" class="form-control" id="quote" placeholder="write the inspirational quote">{{quote.body}}</textarea>
                </div>
                <div class="text-center">
                    <button type="submit" class="btn btn-primary">Update</button>
                </div>

            </form>
        </div>
    </div>
</div>
@endsection

このページには、create-quote.edgeファイルと同様のコンテンツが含まれています。違いは、編集が必要な特定の見積もり<form method="POST" action="/update-quote/テンプレート:Quote.id">の詳細が含まれていることです。

ファイルを保存して終了します。

最後に、1つの感動的な引用を表示するページを生成します。

adonis make:view quotes/quote

次のような出力が表示されます。

Output✔ create  resources/views/quotes/quote.edge

次のコマンドでファイルを開きます。

nano resources/views/quotes/quote.edge

次のコードを追加します。

/resources/views/quotes/quote.edge

@layout('layouts/master')
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-6 offset-md-3">
            <div class="card shadow-lg bg-dark text-white">
                <div class="card-body">
                    <div class="float-right">
                        <a href="/" class="btn btn-outline-primary ">back</a>
                    </div>
                        <br>
                    <div class="clear-fix"></div>
                    <blockquote class="blockquote mb-0">
                        <p>{{quote.body}}</p>
                        <footer class="blockquote-footer">
                            <cite title="Source Title">{{quote.username}}</cite>
                        </footer>
                    </blockquote>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

このページでは、特定の引用の詳細が表示されます。これには、引用の本文quote.bodyと、それを作成した作成者quote.usernameが含まれます。

ファイルの処理が終了したら、保存して終了します。

Edgeテンプレートエンジンを使用して、アプリケーションに必要なすべてのページを作成しました。 次に、アプリケーションのデータベースへの接続を構成して作成します。

ステップ3—データベーススキーマの作成

ここでアプリケーションを提供すると、アプリケーションをデータベースにまだ接続していないため、エラーがスローされます。 このセクションでは、データベースへの接続を設定してから、adonisコマンドを使用して、データベースのテーブルの作成に使用される移行ファイルを生成します。

AdonisJsには、 Lucid ORM という名前のORMが付属しています。これは、データベースを操作するための activerecord実装を提供します。 これにより、データベースからリアルタイムでデータを取得するSQLクエリを作成する手間が省けます。 これは、多くのクエリを必要とする複雑なアプリケーションで作業する場合に特に役立ちます。 例として、アプリケーションからすべての引用符を取得するには、次のように記述します。

const quotes = await Quote.all()

アプリケーションデータベースの適切な構成を続行するには、アプリケーションのルートディレクトリ内にいることを確認し、.envファイルを作成します。

nano .env

新しく作成したファイルを開き、次のコンテンツを追加します。

.env

HOST=127.0.0.1
PORT=3333
NODE_ENV=development
APP_URL=http://${HOST}:${PORT}
CACHE_VIEWS=false
APP_KEY=bTVOEgUvmTCfkvgrK8gEBC3Qxt1xSYr0
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=sammy
DB_PASSWORD=password
DB_DATABASE=adonis
SESSION_DRIVER=cookie
HASH_DRIVER=bcrypt

デフォルトでは、AdonisJsアプリケーションのデータベース接続はSQLiteであり、ここでMySQLに更新します。 また、アプリケーション、アプリケーション環境、およびデータベースのクレデンシャルにPORTを指定します。 DB_USERDB_PASSWORD、およびDB_DATABASEプレースホルダーを自分の資格情報に置き換えてください。

次に、Adonis CLIを使用して、Quoteのモデルと移行ファイルを作成します。 これを行うには、次のコマンドを実行します。

adonis make:model Quote --migration

次のような出力が表示されます。

Output✔ create  app/Models/Quote.js
✔ create  database/migrations/1568209992854_quote_schema.js

このコマンドは、app/ModelsフォルダーにQuoteのモデルを作成し、database/migrationsフォルダーにスキーマファイルを作成します。 新しく作成されたスキーマファイルには、現在のタイムスタンプがプレフィックスとして付けられます。 次のコマンドでスキーマファイルを開きます。

nano database/migrations/1568209992854_quote_schema.js

次のコードでコンテンツを更新します。

データベース/移行/...quote_schema.js

'use strict'
/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')
class QuoteSchema extends Schema {
  up () {
    this.create('quotes', (table) => {
      table.increments()
      table.integer('user_id').notNullable()
      table.string('username', 80).notNullable()
      table.string('body').notNullable()
      table.timestamps()
    })
  }
  down () {
    this.drop('quotes')
  }
}
module.exports = QuoteSchema

AdonisJsのスキーマファイルには、次の2つの異なるメソッドが必要です。

  • up :新しいテーブルを作成したり、既存のテーブルを変更したりするために使用されます。
  • downupメソッドで適用された変更を元に戻すために使用されます。

timestamps()およびincrements()フィールドに加えて、フィールド属性user_idusername、およびbodyuser_idおよびusernameフィールドは、特定の見積もりを作成したユーザーの詳細を参照します。 これは、 1対多の関係を定義し、ユーザーが無限の数の引用符を所有できるのに対し、単一の引用符はユーザーにのみ属することができることを意味します。

ファイルを保存して終了します。

AdonisJsには、デフォルトでUserモデルとその移行ファイルがインストールされており、UserモデルとQuoteモデルの関係を確立するためにわずかな変更を加えるだけで済みます。

app/Models/User.jsUserモデルを開きます。

app/Models/User.js

tokens()メソッドの直後にこのメソッドを追加します。

app / Models / User.js

...
class User extends Model {
  ...
  tokens () {
    return this.hasMany('App/Models/Token')
  }

  quote () {
    return this.hasMany('App/Models/Quote')
  }
}

module.exports = User

これにより、user_idを外部キーとして使用して、Quoteテーブルとの1対多の関係が確立されます。

ファイルを保存して終了します。

このセクションを締めくくるには、次のコマンドを使用して移行を実行します。これにより、すべての移行ファイルのup()メソッドが実行されます。

adonis migration:run

次のような出力が表示されます。

Outputmigrate: 1503248427885_user.js
migrate: 1503248427886_token.js
migrate: 1568209992854_quote_schema.js
Database migrated successfully in 3.42 s

データベースとの接続を構成して保護しました。 また、Quoteモデルとそれに対応するスキーマファイルを作成し、UserQuoteの間に1対多の関係を作成しました。 次に、ルートを生成し、HTTPリクエストを処理するコントローラーと、感動的な見積もりを作成、編集、削除するビジネスロジックを作成します。

ステップ4—コントローラーの作成とルートの設定

このセクションでは、アプリケーションのすべてのロジックを処理するコントローラーを作成することから始め、後でこれらのコントローラーを特定のルートに接続して、ユーザーがURLを介してアクセスできるようにします。

まず、Adonis CLIを使用して、次のコマンドを実行することにより、アプリケーションのすべての認証プロセスを処理する新しいHTTPリクエストコントローラーを作成します。

adonis make:controller Auth --type http

このコマンドは、AuthController.jsファイルを作成し、app/Controllers/Httpフォルダー内に保存します。 フラグ--typeを使用して、このコントローラーをHTTPコントローラーにすることを示します。

次のような出力が表示されます。

Output✔ create  app/Controllers/Http/AuthController.js

次に、新しく作成したコントローラーファイルを開きます。

nano app/Controllers/Http/AuthController.js

次の内容で更新します。

app / Controllers / Http / AuthController.js

'use strict'
const User = use('App/Models/User')
class AuthController {

    loginView({ view }) {
        return view.render('auth.login')
    }
    registrationView({ view }) {
        return view.render('auth.register')
    }

    async postLogin({ request, auth, response}) {
        await auth.attempt(request.input('email'), request.input('password'))
        return response.route('index')
    }

    async postRegister({ request, session, response }) {
        const user = await User.create({
            username: request.input('name'),
            email: request.input('email'),
            password: request.input('password')
        })
        session.flash({ successmessage: 'User have been created successfully'})
        return response.route('login.create');
    }

    async logout ({ auth, response }) {
        await auth.logout()
        return response.route('/')
    }
}
module.exports = AuthController

このファイルでは、Userモデルをインポートしてから、loginView()およびregisterView()という名前の2つのメソッドを作成して、ログインページと登録ページをそれぞれレンダリングします。 最後に、次の非同期メソッドを作成します。

  • postLogin():このメソッドは、AdonisJsに組み込まれているrequestメソッドを使用して投稿された、emailおよびpasswordの値を取得し、このユーザーを検証します。データベースの詳細。 そのようなユーザーがデータベースに存在し、正しいクレデンシャルを入力した場合、新しい見積もりを作成する前に、ユーザーはホームページにリダイレクトされて認証されます。 そうしないと、間違った資格情報を示すメッセージが表示されます。
  • postRegister():これは、ユーザーがデータベースにそのようなユーザーのアカウントを作成するためのusernameemail、およびpasswordの値を受け取ります。 そのようなユーザーが正常に作成されたことを示すメッセージがセッションに渡され、ユーザーはログインページにリダイレクトされて認証を受け、見積もりの作成を開始します。
  • logout():このメソッドはログアウト機能を処理し、ユーザーをホームページにリダイレクトします。

ファイルを保存して終了します。

ユーザーを登録および認証するようにコントローラーを設定したので、次に、見積もりに関するすべての操作を管理するHTTP要求コントローラーを作成します。

ターミナルに戻り、次のコマンドを実行してQuoteControllerを作成します。

adonis make:controller Quote --type http --resource

--resourceフラグを使用すると、CRUD(作成、読み取り、更新、および削除)操作を実行するための事前定義されたリソースの豊富なメソッドを備えたコントローラーが作成されます。

次のように表示されます。

Output✔ create  app/Controllers/Http/QuoteController.js

app/Controllers/Http/QuoteController.js内でこのファイルを見つけます。

nano app/Controllers/Http/QuoteController.js

次の内容で更新します。

app / Controllers / Http / QuoteController.js

'use strict'
const Quote = use('App/Models/Quote')

class QuoteController {

  async index ({ view }) {
    const quote = await Quote.all()
    return view.render('index', {
      quotes: quote.toJSON()
    })
  }

  async create ({ view }) {
    return view.render('quotes.create-quote')
  }

  async store ({ request,auth,session, response }) {
    const quote = await Quote.create({
      user_id: auth.user.id,
      username: auth.user.username,
      body: request.input('body')
    })
    session.flash({ 'successmessage': 'Quote has been created'})
    return response.redirect('/')
  }

  async show ({ params, view }) {
    const quote = await Quote.find(params.id)
    return view.render('quotes.view-quote', {
      quote: quote.toJSON()
    })
  }

  async edit ({ params, view }) {
    const quote = await Quote.find(params.id)
    return view.render('quotes.edit-quote', {
      quote: quote.toJSON()
    })
  }

  async update ({ params, request, response, session }) {
    const quote = await Quote.find(params.id)
    quote.body = request.input('body')
    await quote.save()
    session.flash({'successmessage': 'Quote has been updated'})
    return response.redirect('/')
  }

  async destroy ({ params, response, session }) {
    const quote = await Quote.find(params.id)
    await quote.delete()
    session.flash({'successmessage': 'Quote has been deleted'})
    return response.redirect('/')
  }
}
module.exports = QuoteController

このコントローラーでは、Quoteモデルをインポートし、AdonisJsCLIを使用して自動的に作成された次のメソッドを更新しました。

  • index():データベースからすべての引用符を取得し、アプリケーションのホームページに表示します。
  • create():見積もりを作成するためのページをレンダリングします。
  • store():新しく作成された見積もりをデータベースに保持し、適切な応答を返します。
  • show():特定の見積もりのidを取得するには、データベースから取得して、見積もりの編集ページに表示します。
  • edit():データベースから特定の見積もりの詳細を取得し、編集用にレンダリングします。
  • update():見積もりの更新を処理し、ユーザーをホームページにリダイレクトします。
  • destroy():特定の見積もりを削除し、データベースから完全に削除します。

ファイルを保存して終了します。

このアプリケーションに必要なすべてのコントローラーを作成したら、ユーザーがアプリケーションを簡単に操作できるようにルートを設定できます。 まず、start/routes.jsファイルに移動します

nano start/routes.js

その内容を次のように置き換えます。

start / routers.js

'use strict'
const Route = use('Route')

Route.get('/','QuoteController.index').as('index')
Route.get('/register','AuthController.registrationView').as('register.create')
Route.post('/register-store','AuthController.postRegister').as('register.store').validator('Register')
Route.get('/login','AuthController.loginView').as('login.create')
Route.post('/login-store','AuthController.postLogin').as('login.store')
Route.get('/view-quote/:id','QuoteController.show').as('view.quote')

Route.group(() => {
    Route.get('/create-quote','QuoteController.create').as('create.quote')
    Route.post('/store-quote','QuoteController.store').as('store.quote')
    Route.get('/edit-quote/:id','QuoteController.edit').as('edit.quote')
    Route.post('/update-quote/:id','QuoteController.update').as('update.quote')
    Route.get('/delete-quote/:id','QuoteController.destroy').as('delete.quote')
    Route.post('/logout','AuthController.logout').as('logout')
}).middleware(['auth'])

ここでは、アプリケーションの各ルートのパスを定義し、各アクションのHTTP動詞を指定して、各コントローラーの特定のメソッドにルートをバインドします。 また、コントローラーとビュー内で参照されているため、これらの各ルートに名前を付けます。

認証されたユーザーのみがすべての見積もりルートにアクセスできるようにするには、それに名前を付けたグループミドルウェアを割り当てます。 最後に、バリデーターメソッドをregister.storeルートにアタッチして、ユーザー入力を検証します。

ファイルを保存して終了します。

コントローラを作成し、アプリケーションのルートを設定しました。 次に、このステップで定義されたバリデーターメソッドを作成します。

ステップ5—ユーザー入力の検証

AdonisJsには、デフォルトでバリデーターが組み込まれていません。 その結果、アプリケーションのバリデーターを手動でインストールして登録します。

次のコマンドを実行してインストールします。

adonis install @adonisjs/validator

次のファイルを開いて、バリデータープロバイダーを登録します。

nano start/app.js

次に、次に示すように、プロバイダーのリストにバリデータープロバイダーを追加して、バリデータープロバイダーを登録します。

start / app.js

...
const providers = [
   ...
   '@adonisjs/cors/providers/CorsProvider',
   '@adonisjs/shield/providers/ShieldProvider',
   '@adonisjs/session/providers/SessionProvider',
   '@adonisjs/auth/providers/AuthProvider',
   '@adonisjs/validator/providers/ValidatorProvider'
]

アプリケーション内にバリデータープロバイダーをインストールして登録したので、次のコマンドを使用して、登録中にユーザー入力を検証するカスタムバリデーターを作成します。

adonis make:validator Register

これにより、App/validatorsディレクトリにRegister.jsファイルが作成されます。 次のコマンドでファイルを開きます。

nano app/Validators/Register.js

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

app / Validators / Register.js

'use strict'
class Register {
  get rules () {
    return {
      name:'required',
      email:'required|email|unique:users',
      password:'required|min:8'
    }
  }

  get messages(){
    return{
      'name.required':'Full name is required',
      'email.required':'email is required',
      'email.unique':'email already exists',
      'password.required':'password is required',
      'password.min':'password should be at least 8 characters'
    }
  }
}
module.exports = Register

アプリケーションの特定のフィールドのルールを定義します。 検証がいつでも失敗した場合、バリデーターはエラーをフラッシュメッセージとして自動的に設定し、ユーザーはフォームにリダイレクトされます。

編集が終了したら、ファイルを保存して終了します。

最後に、アプリケーションのスタイルを追加するには、次のファイルを開きます。

nano public/style.css

その内容を次のように置き換えます。

/public/style.css

@import url('https://fonts.googleapis.com/css?family=Montserrat:300');

html, body {
  height: 100%;
  width: 100%;
}

body {
  font-family: 'Montserrat', sans-serif;
  font-weight: 300;
  background-image: url("/splash.png");
  background-color: #220052;
}

* {
  margin: 0;
  padding: 0;
}

a {
  color: inherit;
  text-decoration: underline;
}

p {
  margin: 0.83rem 0;
}

.quote-wrapper {
  margin-top: 20px;
}

.quote-wrapper a {
  text-decoration: none;
}

.quote-wrapper a:hover {
  color: #ffffff;
}

.empty-quote {
  color: #ffffff;
}

form {
  padding: 20px;
}

このファイルでは、style.cssファイルでアプリケーションのCSSスタイルを更新します。

登録プロセス中にユーザーの入力を確認する目的で、バリデータープロバイダーをインストールして登録しました。 また、スタイルシートの内容を更新して、アプリケーションにスタイルを追加しました。 最後のステップでは、アプリケーションをテストします。

ステップ6—アプリケーションの提供

このステップでは、アプリケーションを提供し、認証をテストするためのユーザーとパスワードを作成します。 また、アプリに見積もりを追加して、ホームページで表示します。

アプリケーションをテストするには、アプリケーションのルートディレクトリから次のコマンドを使用して開発サーバーを起動します。

adonis serve --dev

これにより、ルート.envファイル内で定義されたポート(3333)でアプリケーションが起動します。 ブラウザからhttp:// localhost:3333に移動します。

見積もりを作成していないため、現時点ではホームページは空です。 登録ボタンをクリックしてください。

詳細を入力し、送信ボタンをクリックして登録プロセスを完了します。 ログインページにリダイレクトされます。 認証用のメールアドレスとパスワードを入力します。

認証されたら、見積もりの作成ボタンをクリックします。

見積もりを入力し、すべて表示ページに移動して見積もりを表示します。

ユーザーを作成して認証し、見積もりを作成して、アプリケーションをテストしました。

結論

このチュートリアルでは、AdonisJsを使用してWebアプリケーションを構築しました。 AdonisJs CLIを使用してアプリケーションをセットアップし、CLIを利用して、コントローラー、モデル、ビューなどの他の関連ファイルを作成しました。

サイズや複雑さに関係なく、このフレームワークを使用してWebアプリケーションを構築できます。 このプロジェクトのソースコードここをGitHubからダウンロードしてください。 その他の機能については、公式ドキュメントにアクセスすることもできます。

他のJavaScriptフレームワークのチュートリアルをご覧になりたい場合は、以下をご覧ください。