如何使用 AdonisJs 和 MySQL 构建励志名言应用程序

作者选择了 技术教育基金作为 写给捐款计划的一部分接受捐款。

介绍

AdonisJs是用JavaScript(https://en.wikipedia.org/wiki/JavaScript)编写的Node.js(https://nodejs.org/en/)网页框架,在所有主要操作系统上运行,它使用受欢迎的MVC(模型 - 视图 - 控制器)](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)设计模式,并为书写服务器侧 Web 应用程序提供稳定的生态系统。该框架具有无缝的 身份验证,SQL ORM(对象关系地图), 迁移数据库种子.AdonisJs具有类似的 PHP Web 应用框架(Laravel](https://laravel.com/),包括相同的文件夹结构和多个共享设置概念。

默认情况下,AdonisJs 使用的是为直观使用而设计的 Edge 模板引擎,与 Laravel 一样,AdonisJs 使用一个名为 Lucid的 ORM,它作为应用程序模型与数据库之间的通信接口。 使用AdonisJs,开发人员可以构建一个完整的应用程序,后端服务器将负责应用业务逻辑、路由和对应用程序的所有页面进行渲染。 还可以创建 Web 服务 API 来返回控制器的 JSON 响应;这些 Web 服务可以使用前端框架,如 Vue.js, React,和 Angular来消耗。

在本教程中,您将使用其 CLI 构建一个应用程序,使用 AdonisJs. 您将在您的应用程序中创建路径,控制器,模型和视图,并进行表单验证。本教程中的示例将是一个鼓舞人心的引用应用程序,用户可以登录并登录创建一个鼓舞人心的引用程序。

前提条件

在您开始本指南之前,您将需要以下内容:

Node.js 是一个 JavaScript 运行时环境,允许您在浏览器之外运行代码。它配有预安装的包管理器,名为 npm,允许您安装和更新包。 若要在 macOS 或 Ubuntu 18.04 上安装这些包,请遵循 如何在 macOS 上安装 Node.js 并创建本地开发环境或 [如何在 Ubuntu 18.04 上安装 Node.js 的 PPA 部分**的 ** 安装]的步骤。 * MySQL 安装在您的机器上。 请遵循 这里下载并安装到您选择的操作系统中。 若要成功地安装 MySQL,您可以通过使用 [Hebrewom] 编辑器在 Mac 上https://code.visualstudio.com/ 安装它。 如何在 Ubuntu 中安装我们的 JavaScript

<$>[注] 注: 本教程使用 macOS 机器进行开发. 如果您正在使用其他操作系统,您可能需要在第一步中使用sudo用于npm命令。

步骤 1 – 安装 Adonis CLI

在本节中,您将在本地机器上安装 Adonis CLI及其所有所需的包,该 CLI 将允许您创建一个新的 AdonisJs 项目,并为您的应用程序中控制器,中间件和模型创建和生成锅炉板。

运行以下命令以通过npm在您的机器上全球安装 AdonisJs CLI:

1npm i -g @adonisjs/cli

一旦安装过程完成,请在终端中输入以下命令,以确认 AdonisJs 的安装并查看当前版本:

1adonis --version

您将看到显示当前版本的 AdonisJs 的输出:

1[secondary_label Output]
24.1.0

随着AdonisJs CLI的成功安装,您现在可以访问并使用adonis命令创建AdonisJs项目的新安装,管理您的项目,并生成相关文件,如控制器,模型等。

现在,您可以使用adonis命令来创建一个新的AdonisJs项目,如下所示:

1adonis new adonis-quotes-app

上一个命令将创建一个名为adonis-quotes-app的应用程序,在您的本地项目目录中创建一个名为adonis-quotes-app的新目录,并使用相关的 AdonisJs MVC 结构。

移动到新应用程序文件夹:

1cd adonis-quotes-app

然后通过运行开始您的应用程序:

1adonis serve --dev

这将启动开发服务器的默认端口 3333 如在您的应用程序的 root .env 文件中指定。

Welcome page of AdonisJs

在这里,您将安装 mysql 驱动程序连接到您的 MySQL 服务器从您的 Node.js 应用程序通过 npm

1npm i mysql

现在,您已经成功安装了此应用程序的 MySQL Node.js 驱动程序,您需要创建应用程序数据库并设置相应的连接。

您从前提教程中安装的最新版本的 MySQL 使用一个名为 caching_sha2_password的默认身份验证插件。 此功能目前不受 MySQL 的 Node.js 驱动程序的支持。 为了避免应用程序中的任何数据库连接问题,您需要创建一个新的 MySQL 用户并使用目前支持的身份验证插件 -mysql_native_password

首先,请使用 root 帐户访问 MySQL 客户端:

1mysql -u root -p

您将被要求在 MySQL 安装过程中输入您的 root 帐户密码。

接下来,使用mysql_native_password插件创建用户和密码:

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

您将看到以下结果:

1[secondary_label Output]
2Query OK, 0 rows affected (0.02 sec)

接下来,为应用程序创建一个数据库:

1CREATE DATABASE adonis;

您将看到以下结果:

1[secondary_label Output]
2Query OK, 1 row affected (0.03 sec)

您现在已经成功创建了此应用程序的数据库。

现在,为新 MySQL 用户启用访问创建的数据库,运行以下命令,向数据库中的用户授予所有权限:

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

通过运行以下命令重新加载授权表,以应用您刚刚做的更改:

1FLUSH PRIVILEGES;

您将看到以下结果:

1[secondary_label Output]
2Query OK, 0 rows affected (0.00 sec)

退出 MySQL 客户端:

1quit;

你已经成功安装了AdonisJs CLI,创建了一个新的AdonisJs项目,并通过npm安装了mysql。你还创建了这个应用程序的数据库,并为它设置了一个MySQL用户,具有相应的特权。

第2步:使用边缘模板引擎

AdonisJs配备了自己的模板引擎,名为 Edge。它允许您创建可重复使用的HTML模板,并允许在最少的代码下将前端逻辑引入您的应用程序。Edge为JavaScript开发人员提供开发应用程序时的工具,以构建基于组件的布局,写条件,使用迭代,并创建视图层以保持逻辑。

以下是您的应用程序需要正常运作的观点:

  • 主布局 :使用Edge,您可以创建一个包含CSS、常见JavaScript文件、jQuery和常见用户界面部分的页面,这些页面将在整个应用程序中保持相同,例如导航栏、标志、标题等:一旦您设置了主布局页面,您的应用程序中的其他视图(页面)将继承它。 * ** 索引视图** :本页面将使用主布局来继承常见文件,并还会为应用程序的首页提供内容。 * ** 登录页面** :本页面还将使用主布局,并将该表单与用户登录的用户名和密码的输入字段进行渲染。 * ** 登录页面:在这里,用户将看到一个表单,并将其详细信息存储在数据库中。 *

首先,使用adonis命令创建主布局页,运行以下命令:

1adonis make:view layouts/master

您将看到类似于以下的输出:

1[secondary_label Output]
2✔ create resources/views/layouts/master.edge

此命令将自动在您的资源/视图/布局文件夹中创建一个master.edge文件。

1nano resources/views/layouts/master.edge

把以下代码插入其中:

 1[label /resources/views/layouts/master.edge]
 2<!DOCTYPE html>
 3<html lang="en">
 4<head>
 5    <meta charset="UTF-8">
 6    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 8    <title>adonis-quotes-app</title>
 9    {{ style('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css') }}
10    {{ style('style') }}
11    {{ script('https://code.jquery.com/jquery-3.3.1.slim.min.js') }}
12</head>
13<body>
14    <div class="container-fliud">
15        @include('navbar')
16        @!section('content')
17    </div>
18    {{ script('https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js') }}
19
20</body>
21</html>

在此檔案中,你包括了 Bootstrap CSS, Bootstrap JavaScript,jQuery的 CDN 檔案。你添加了「style.css」的全球 CSS 檔案名稱,而在「div」中,你包括了一個名為「navbar」的 partial 檔案。要在你的應用程式中複數頁面中重複使用你需要的 HTML 代碼片段,例如「nav」或「footer」,你可以嵌入部分檔案。這些是包含重複代碼的小檔案,讓您更快地更新這些元素的代碼,而不是每次發生。「navbar」包含一個 Login 和 ** Register** 按鈕,一個標誌和一個主頁連結。

有了这一点,将为此应用程序创建的所有后续页面可以扩展主布局,并在不需要重新写内容的情况下渲染navbar

最后,您定义一个部分标签 @!section() 以包括来自其他页面的内容,并让它们通过主布局进行渲染。

保存和退出文件,一旦你完成编辑它。

接下来,您将使用adonis命令创建导航栏:

1adonis make:view navbar

你会看到类似的输出:

1[secondary_label Output]
2✔ create resources/views/navbar.edge

打开新创建的文件:

1nano resources/views/navbar.edge

然后添加以下代码:

 1[label /resources/views/navbar.edge]
 2<nav class="navbar navbar-expand-lg navbar-dark text-white">
 3    <a class="navbar-brand" >LOGO</a>
 4    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
 5        <span class="navbar-toggler-icon"></span>
 6    </button>
 7
 8    <div class="collapse navbar-collapse" id="navbarNav">
 9        <ul class="navbar-nav">
10            <li class="nav-item active ">
11                <a class="btn text-white" href="/">Home</a>
12            </li>
13        </ul>
14    </div>
15    <div class="navbar-right" id="navbarNav">
16        @loggedIn
17            <ul class="navbar-nav">
18                    <li>
19                        <div class="text-right">
20                             <a href="{{route('create.quote')}}" class="btn btn-outline-primary">Create Quote</a>
21                        </div>
22                    </li>
23
24                <li class="nav-item dropdown">
25                    <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
26                       {{ auth.user.username}}
27                    </a>
28                    <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
29                        <form method="POST" action="{{route('logout')}}">
30                            {{ csrfField() }}
31                              <button type="submit" class="dropdown-item" href="">logout</button>
32                        </form>
33                    </div>
34                </li>
35            </ul>
36        @else
37            <ul class="navbar-nav">
38                <li class="nav-item active pr-2">
39                    <a href="{{route('login.create')}}" class="btn btn-outline-danger">
40                      login
41                    </a>
42                </li>
43                <li class="nav-item active pr-2">
44                    <a href="{{route('register.create')}}" class="btn btn-outline-primary">
45                        Register
46                    </a>
47                </li>
48            </ul>
49        @endloggedIn
50    </div>
51</nav>

除了定义主页的链接和注册和登录按钮外,您还添加了一个@loggedIn标签。在此处,您可以写一个有条件的声明,围绕被验证的用户,并在必要时显示适当的内容。对于被验证的用户,应用程序将显示他们的用户名和创建新报价的按钮。如果用户没有登录,您的应用程序将显示一个按钮,以登录或注册。此页面将被列入每个页面的一部分,就像以前在该应用程序的主布局中一样。

保存和退出文件。

现在,你将创建你将用于应用程序的主页的索引页面. 它将渲染和显示用户写的所有鼓舞人心的引文列表:

1adonis make:view index

您将看到类似于以下的输出:

1[secondary_label Output]
2✔ create resources/views/index.edge

这里创建的文件将位于资源/视图/index.edge

1nano resources/views/index.edge

然后添加以下代码:

 1[label /resources/views/index.edge]
 2@layout('layouts/master')
 3@section('content')
 4
 5<div class="container">
 6    <div class="text-center">
 7        @if(flashMessage('successmessage'))
 8            <span class="alert alert-success p-1">{{ flashMessage('successmessage') }}</span>
 9        @endif
10    </div>
11    <div class="row">
12        @each(quote in quotes)
13            <div class="col-md-4 mb-4 quote-wrapper">
14                <a href="/view-quote/{{quote.id}}" class="w-100">
15                    <div class="card shadow-lg bg-dark text-white">
16                        <div class="card-body">
17                            <blockquote class="blockquote mb-0">
18                                <p>{{quote.body}}</p>
19                                <footer class="blockquote-footer">
20                                    <cite title="Source Title"> {{quote.username}}</cite>
21                                </footer>
22                            </blockquote>
23                            @if(auth.user.id == quote.user_id)
24                              <div>
25                                <a href="/edit-quote/{{quote.id}}" class="btn btn-primary">edit</a>
26                                <a href="/delete-quote/{{quote.id}}" class="btn btn-danger">delete</a>
27                              </div>
28                            @endif
29                        </div>
30                    </div>
31                </a>
32            </div>
33        @else
34         <div class="col-md-12 empty-quote text-center">
35                <p>No inspirational quote has been created</p>
36         </div>
37        @endeach
38    </div>
39</div>
40@endsection

在这里,您表示此视图将通过扩展使用布局。此页面现在可以访问包含在布局中的所有库、风格表和navbar。接下来,您会使用内置的@each标签重复使用一系列的引文引文布局将从您在本教程中稍后创建的QuoteController传递到此视图。如果没有引文,将显示适当的消息。

保存和退出此文件。

现在,要创建登录页面,请从终端执行以下命令:

1adonis make:view auth/login

你会看到一个类似的输出:

1[secondary_label Output]
2✔ create resources/views/auth/login.edge

这将自动在资源/视图中创建一个auth文件夹,并在其中创建一个login.edge文件。

1nano resources/views/auth/login.edge

添加以下内容:

 1[label /resources/views/auth/login.edge]
 2@layout('layouts/master')
 3@section('content')
 4  <div class="container">
 5    <div class="row">
 6      <div class="col-md-4 shadow bg-white mt-5 rounded offset-md-4">
 7        <form method="POST" action="{{route('login.store')}}">
 8          {{ csrfField() }}
 9            <div>
10              @if(flashMessage('successmessage'))
11                <span class="alert alert-success p-1">{{ flashMessage('successmessage') }}</span>
12              @endif
13            </div>
14            <div class="form-group">
15              <label for="email">Email address</label>
16              <input type="email" class="form-control" id="email" name="email" value="{{old('email','')}}"  placeholder="Enter email">
17              {{ elIf('<span class=text-danger>$self</span>', getErrorFor('email'), hasErrorFor('email')) }}
18            </div>
19            <div class="form-group">
20              <label for="pasword">Password</label>
21              <input type="password" class="form-control" id="password" name="password" value="{{old('password','')}}" placeholder="Password">
22              {{ elIf('<span class=text-danger>$self</span>', getErrorFor('password'), hasErrorFor('password')) }}
23            </div>
24
25            <div class="text-center">
26              <button type="submit" class="btn btn-primary">Submit</button>
27            </div>
28        </form>
29      </div>
30    </div>
31  </div>
32@endsection

该文件包含一个包含输入元素的表单,您将使用它来收集注册用户的用户名和密码,然后他们可以成功验证并开始创建报价。在本页面上需要注意的另一个重要元素是{{ csrfField() }}

它通过为每个访问您的网站的用户生成一个独特的CSRF秘密,一旦您的用户从前端发送了HTTP请求,将为此秘密生成相应的代币,并与请求一起传递。

保存和退出文件一旦完成。

接下来,您将使用此命令创建注册表页面:

1adonis make:view auth/register

您将看到类似于此的输出:

1[secondary_label Output]
2✔ create resources/views/auth/register.edge

resources/views/auth/register.edge中找到并打开新创建的文件:

1nano resources/views/auth/register.edge

添加以下代码:

 1[label resources/views/auth/register.edge]
 2@layout('layouts/master')
 3@section('content')
 4  <div class="container ">
 5    <div class="row">
 6        <div class="col-md-4 bg-white p-3 mt-5 shadow no-border rounded offset-md-4">
 7          <form method="POST" action="{{route('register.store')}}">
 8            {{ csrfField() }}
 9              <div class="form-group">
10                <label for="name">Fullname</label>
11                <input type="text" class="form-control" id="name" name="name"  value="{{old('name','')}}" placeholder="Enter Fullname">
12                {{ elIf('<span class=text-danger>$self</span>', getErrorFor('name'), hasErrorFor('name')) }}
13              </div>
14              <div class="form-group">
15                <label for="email">Email address</label>
16                <input type="email" class="form-control" id="email"  name="email" value="{{old('email','')}}" placeholder="Enter email">
17                {{ elIf('<span class=text-danger>$self</span>', getErrorFor('email'), hasErrorFor('email')) }}
18              </div>
19              <div class="form-group">
20                <label for="pasword">Password</label>
21                <input type="password" class="form-control" id="password" name="password" placeholder="Password">
22                {{ elIf('<span class=text-danger>$self</span>', getErrorFor('password'), hasErrorFor('password')) }}
23              </div>
24              <div class="text-center">
25                  <button type="submit" class="btn btn-primary">Submit</button>
26              </div>
27          </form>
28        </div>
29    </div>
30  </div>
31@endsection

类似于你在登录页面上,这个文件包含一个HTML表格,包含输入字段来收集用户在注册过程中的名称,电子邮件密码

保存和退出文件。

现在,您将生成一个新的文件,通过从终端运行以下命令来创建一个鼓舞人心的报价:

1adonis make:view quotes/create-quote

你会看到这样的输出:

1[secondary_label Output]
2✔ create resources/views/quotes/create-quote.edge

打开资源/观点/引用/create-quote.edge:

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

并添加以下内容:

 1[label /resources/views/quotes/create-quote.edge]
 2@layout('layouts/master')
 3@section('content')
 4<div class="container">
 5    <div class="row">
 6        <div class="col-md-3"></div>
 7        <div class="col-md-6 shadow bg-white mt-5 rounded p-3">
 8            <div class="float-right">
 9                <a href="/" class="btn btn-outline-dark ">back</a>
10            </div>
11                <br>
12
13            <div class="clear-fix"></div>
14                <form method="POST" action="{{route('store.quote')}}">
15                    {{ csrfField() }}
16                    <div class="form-group">
17                        <label for="quote">Create Quote</label>
18                        <textarea type="text" rows="5"  name='body' id="body" class="form-control" id="quote" placeholder="Write an inspirational quote"></textarea>
19                    </div>
20
21                    <div class="text-center">
22                        <button type="submit" class="btn btn-primary">Submit</button>
23                    </div>
24                </form>
25            </div>
26        </div>
27        <div class="col-md-3"></div>
28    </div>
29</div>
30@endsection

此页面扩展了主布局,并包含一个HTML表格,包含一个文本区域元素,允许用户在发布并处理相应路径之前在多个行内输入文本。

保存和退出文件一旦完成。

接下来,您将创建一个页面来编辑特定的报价,从终端执行以下命令:

1adonis make:view quotes/edit-quote

您将看到以下结果:

1[secondary_label Output]
2✔ create resources/views/quotes/edit-quote.edge

打开文件与:

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

将下列内容添加到资源/观点/引文/编辑引文中:

 1[label /resources/views/quotes/edit-quote.edge]
 2@layout('layouts/master')
 3@section('content')
 4<div class="container">
 5    <div class="row">
 6        <div class="col-md-6 shadow bg-white rounded p-3 offset-md-3">
 7            <div class="float-right">
 8                <a href="/" class="btn btn-outline-dark ">back</a>
 9            </div>
10            <br>
11
12            <div class="clear-fix"></div>
13            <form method="POST" action="/update-quote/{{quote.id}}">
14                {{ csrfField() }}
15                <div class="form-group">
16                    <label for="pasword">Edit Quote</label>
17                    <textarea type="text" rows="5"  name='body' id="body" class="form-control" id="quote" placeholder="write the inspirational quote">{{quote.body}}</textarea>
18                </div>
19                <div class="text-center">
20                    <button type="submit" class="btn btn-primary">Update</button>
21                </div>
22
23            </form>
24        </div>
25    </div>
26</div>
27@endsection

此页面包含类似于 create-quote.edge 文件的内容 - 区别在于它包含需要编辑的特定引文的详细信息, `

保存和退出文件。

最后,生成页面以查看单个鼓舞人心的引用:

1adonis make:view quotes/quote

您将看到类似于此的输出:

1[secondary_label Output]
2✔ create resources/views/quotes/quote.edge

打开文件与:

1nano resources/views/quotes/quote.edge

添加以下代码:

 1[label /resources/views/quotes/quote.edge]
 2@layout('layouts/master')
 3@section('content')
 4<div class="container">
 5    <div class="row">
 6        <div class="col-md-6 offset-md-3">
 7            <div class="card shadow-lg bg-dark text-white">
 8                <div class="card-body">
 9                    <div class="float-right">
10                        <a href="/" class="btn btn-outline-primary ">back</a>
11                    </div>
12                        <br>
13                    <div class="clear-fix"></div>
14                    <blockquote class="blockquote mb-0">
15                        <p>{{quote.body}}</p>
16                        <footer class="blockquote-footer">
17                            <cite title="Source Title">{{quote.username}}</cite>
18                        </footer>
19                    </blockquote>
20                </div>
21            </div>
22        </div>
23    </div>
24</div>
25@endsection

此頁面顯示了一個特定的引文的細節,其中包括引文的身體「quote.body」和創作者的名字「quote.username」。

一旦你完成了文件,保存和退出。

您已经使用 Edge 模板引擎为您的应用程序创建了所有所需的页面,接下来,您将配置并创建连接到应用程序的数据库。

步骤 3 – 创建数据库计划

如果您现在服务您的应用程序,它会引发错误,因为您尚未将应用程序连接到数据库. 在本节中,您将建立连接到数据库,然后使用adonis命令生成一个迁移文件,将用于创建该数据库的表。

AdonisJs 配备了一个名为 Lucid ORM的 ORM,它提供了 活跃记录的实现,以便与您的数据库工作。 它消除了编写实时从数据库中获取数据的 SQL 查询的麻烦。

1const quotes = await Quote.all()

要进行适当的应用程序数据库配置,请确保您仍然在应用程序的 root 目录中,并创建一个 .env 文件:

1nano .env

打开新创建的文件并添加以下内容:

 1[label .env]
 2HOST=127.0.0.1
 3PORT=3333
 4NODE_ENV=development
 5APP_URL=http://${HOST}:${PORT}
 6CACHE_VIEWS=false
 7APP_KEY=bTVOEgUvmTCfkvgrK8gEBC3Qxt1xSYr0
 8DB_CONNECTION=mysql
 9DB_HOST=127.0.0.1
10DB_PORT=3306
11DB_USER=sammy
12DB_PASSWORD=password
13DB_DATABASE=adonis
14SESSION_DRIVER=cookie
15HASH_DRIVER=bcrypt

默认情况下,AdonisJs应用程序的数据库连接是SQLite,您将在这里更新到MySQL。您还会指定应用程序、应用程序环境和数据库凭证的PORT

接下来,您将使用 Adonis CLI 创建模型和迁移文件,运行以下命令:

1adonis make:model Quote --migration

您将看到类似于以下的输出:

1[secondary_label Output]
2✔ create app/Models/Quote.js
3✔ create database/migrations/1568209992854_quote_schema.js

此命令将在应用程序/模型文件夹中创建一个模型,并在数据库/迁移文件夹中创建一个模型。

1nano database/migrations/1568209992854_quote_schema.js

用以下代码更新其内容:

 1[label database/migrations/...quote_schema.js]
 2'use strict'
 3/** @type {import('@adonisjs/lucid/src/Schema')} */
 4const Schema = use('Schema')
 5class QuoteSchema extends Schema {
 6  up () {
 7    this.create('quotes', (table) => {
 8      table.increments()
 9      table.integer('user_id').notNullable()
10      table.string('username', 80).notNullable()
11      table.string('body').notNullable()
12      table.timestamps()
13    })
14  }
15  down () {
16    this.drop('quotes')
17  }
18}
19module.exports = QuoteSchema

AdonisJs中的方案文件需要两种不同的方法,这些方法是:

  • ** up** :用于创建新表或更改现有表。 * ** down** :用于逆转 up方法中应用的更改。

除了timestamps()increments()字段外,您还会更新方案文件的内容,使用将创建的引文的字段属性user_id,usernamebodyuser_idusername字段将引用创建特定引文的用户的详细信息。

保存和退出文件。

AdonisJs 默认安装了用户模型及其迁移文件,只需要一个小小的修改来建立用户报价模型之间的关系。

app/Models/User.js中打开用户模型:

1app/Models/User.js

tokens()方法后立即添加此方法:

 1[label app/Models/User.js]
 2...
 3class User extends Model {
 4  ...
 5  tokens () {
 6    return this.hasMany('App/Models/Token')
 7  }
 8
 9  quote () {
10    return this.hasMany('App/Models/Quote')
11  }
12}
13
14module.exports = User

这将建立与使用user_id作为外部密钥的引用表的一个至多个关系。

保存和退出文件。

要包装此部分,请使用以下命令运行迁移,该命令将执行所有迁移文件的 up() 方法:

1adonis migration:run

您将看到类似于以下的输出:

1[secondary_label Output]
2migrate: 1503248427885_user.js
3migrate: 1503248427886_token.js
4migrate: 1568209992854_quote_schema.js
5Database migrated successfully in 3.42 s

你还创建了一个引用模型及其相应的架构文件,并创建了一个用户引用之间的关系,然后,你将生成路线和创建控制器来处理HTTP请求和商业逻辑,以创建,编辑和删除令人鼓舞的引用。

步骤 4 – 创建控制器和设置路线

在本节中,您将首先创建控制器来处理应用程序的所有逻辑,然后将这些控制器附加到特定路径,以便用户通过URL访问它。

首先,您将使用 Adonis CLI 创建一个新的 HTTP 请求控制器,以运行以下命令来处理您的应用程序的所有身份验证流程:

1adonis make:controller Auth --type http

此命令将创建一个AuthController.js文件,并将其保存到app/Controllers/Http文件夹中。

您将看到类似于以下的输出:

1[secondary_label Output]
2✔ create app/Controllers/Http/AuthController.js

接下来,打开新创建的控制器文件:

1nano app/Controllers/Http/AuthController.js

更新它以以下内容:

 1[label app/Controllers/Http/AuthController.js]
 2'use strict'
 3const User = use('App/Models/User')
 4class AuthController {
 5
 6    loginView({ view }) {
 7        return view.render('auth.login')
 8    }
 9    registrationView({ view }) {
10        return view.render('auth.register')
11    }
12
13    async postLogin({ request, auth, response}) {
14        await auth.attempt(request.input('email'), request.input('password'))
15        return response.route('index')
16    }
17
18    async postRegister({ request, session, response }) {
19        const user = await User.create({
20            username: request.input('name'),
21            email: request.input('email'),
22            password: request.input('password')
23        })
24        session.flash({ successmessage: 'User have been created successfully'})
25        return response.route('login.create');
26    }
27
28    async logout ({ auth, response }) {
29        await auth.logout()
30        return response.route('/')
31    }
32}
33module.exports = AuthController

在此文件中,您导入用户模型,然后创建名为loginView()registerView()的两种方法,分别使登录和注册页面。

  • postLogin():此方法将通过AdonisJs内置的‘请求’方法获取‘电子邮件’和‘密码’的值,然后对该用户进行验证。如果该用户存在于数据库中,并输入了正确的凭证,则将重定向到主页并验证,然后可以创建新的报价。否则,将显示一个表示错误的报价的消息。 * postRegister():此信息将收到用户创建该用户帐户的‘用户名’、‘电子邮件’和‘密码’的值。 指示该用户已成功创建的消息将传递到会话中,用户将被重定向到登录页面,以获得验证并开始创建报价。 * outlog():此方法将处理登录功能并将用户重定

保存和退出文件。

现在您已经设置了注册和身份验证用户的控制器,您将创建一个 HTTP 请求控制器来管理有关报价的所有操作。

回到终端,运行以下命令来创建QuoteController:

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

使用资源旗帜将创建具有预定义资源的方法的控制器,以执行 CRUD(创建,阅读,更新和删除)操作。

你会看到:

1[secondary_label Output]
2✔ create app/Controllers/Http/QuoteController.js

app/Controllers/Http/QuoteController.js中找到此文件:

1nano app/Controllers/Http/QuoteController.js

更新它以以下内容:

 1[label app/Controllers/Http/QuoteController.js]
 2'use strict'
 3const Quote = use('App/Models/Quote')
 4
 5class QuoteController {
 6
 7  async index ({ view }) {
 8    const quote = await Quote.all()
 9    return view.render('index', {
10      quotes: quote.toJSON()
11    })
12  }
13
14  async create ({ view }) {
15    return view.render('quotes.create-quote')
16  }
17
18  async store ({ request,auth,session, response }) {
19    const quote = await Quote.create({
20      user_id: auth.user.id,
21      username: auth.user.username,
22      body: request.input('body')
23    })
24    session.flash({ 'successmessage': 'Quote has been created'})
25    return response.redirect('/')
26  }
27
28  async show ({ params, view }) {
29    const quote = await Quote.find(params.id)
30    return view.render('quotes.view-quote', {
31      quote: quote.toJSON()
32    })
33  }
34
35  async edit ({ params, view }) {
36    const quote = await Quote.find(params.id)
37    return view.render('quotes.edit-quote', {
38      quote: quote.toJSON()
39    })
40  }
41
42  async update ({ params, request, response, session }) {
43    const quote = await Quote.find(params.id)
44    quote.body = request.input('body')
45    await quote.save()
46    session.flash({'successmessage': 'Quote has been updated'})
47    return response.redirect('/')
48  }
49
50  async destroy ({ params, response, session }) {
51    const quote = await Quote.find(params.id)
52    await quote.delete()
53    session.flash({'successmessage': 'Quote has been deleted'})
54    return response.redirect('/')
55  }
56}
57module.exports = QuoteController

在此控制器中,您导入了评分模型,并更新了使用 AdonisJs CLI 自动创建的以下方法:

  • index():从数据库中获取所有引用,并在应用程序的主页上渲染。 * create(): 渲染用于创建引用的页面. * store(): 将新创建的引用留入数据库并返回适当的响应. * show(): 获取特定引用的 id,从数据库中获取,并在编辑引用页面上渲染。

保存和退出文件。

在为此应用程序创建所有必要的控制器后,您现在可以设置路径,以便用户可以轻松与您的应用程序进行交互。

1nano start/routes.js

将其内容替换为如下:

 1[label start/routes.js]
 2'use strict'
 3const Route = use('Route')
 4
 5Route.get('/','QuoteController.index').as('index')
 6Route.get('/register','AuthController.registrationView').as('register.create')
 7Route.post('/register-store','AuthController.postRegister').as('register.store').validator('Register')
 8Route.get('/login','AuthController.loginView').as('login.create')
 9Route.post('/login-store','AuthController.postLogin').as('login.store')
10Route.get('/view-quote/:id','QuoteController.show').as('view.quote')
11
12Route.group(() => {
13    Route.get('/create-quote','QuoteController.create').as('create.quote')
14    Route.post('/store-quote','QuoteController.store').as('store.quote')
15    Route.get('/edit-quote/:id','QuoteController.edit').as('edit.quote')
16    Route.post('/update-quote/:id','QuoteController.update').as('update.quote')
17    Route.get('/delete-quote/:id','QuoteController.destroy').as('delete.quote')
18    Route.post('/logout','AuthController.logout').as('logout')
19}).middleware(['auth'])

在这里,您可以定义应用程序中的每个路径的路径,为每个操作指定 HTTP 词汇,并将路径与每个控制器中的特定方法相关联。

为了确保只有经过身份验证的用户才能访问所有报价路线,您将为该路线分配一个名为中间软件的组,最后,您将验证方法附加到register.store路线,以验证用户输入。

保存和退出文件。

您已经创建了控制器并为您的应用程序设置了路线,接下来您将创建本步定义的验证方法。

步骤5:验证用户输入

AdonisJs 默认情况下没有内置验证器,因此您将手动安装和注册您的应用程序的验证器。

运行以下命令来安装它:

1adonis install @adonisjs/validator

打开以下文件来注册验证器提供商:

1nano start/app.js

然后注册验证器提供商,将其附加到以下提供商列表中:

 1[label start/app.js]
 2...
 3const providers = [
 4   ...
 5   '@adonisjs/cors/providers/CorsProvider',
 6   '@adonisjs/shield/providers/ShieldProvider',
 7   '@adonisjs/session/providers/SessionProvider',
 8   '@adonisjs/auth/providers/AuthProvider',
 9   '@adonisjs/validator/providers/ValidatorProvider'
10]

现在您已经在应用程序中安装并注册了验证器提供商,您可以使用以下命令创建自定义验证器来验证用户输入:

1adonis make:validator Register

这将在应用程序/验证器目录中创建一个Register.js文件。

1nano app/Validators/Register.js

将以下代码添加到文件中:

 1[label app/Validators/Register.js]
 2'use strict'
 3class Register {
 4  get rules () {
 5    return {
 6      name:'required',
 7      email:'required|email|unique:users',
 8      password:'required|min:8'
 9    }
10  }
11
12  get messages(){
13    return{
14      'name.required':'Full name is required',
15      'email.required':'email is required',
16      'email.unique':'email already exists',
17      'password.required':'password is required',
18      'password.min':'password should be at least 8 characters'
19    }
20  }
21}
22module.exports = Register

如果验证在任何时候失败,验证器会自动将错误设置为闪存消息,用户将被重定向回表单。

保存和退出文件,一旦你完成编辑。

最后,要为您的应用程序添加风格,请打开以下文件:

1nano public/style.css

将其内容替换为如下:

 1[label /public/style.css]
 2@import url('https://fonts.googleapis.com/css?family=Montserrat:300');
 3
 4html, body {
 5  height: 100%;
 6  width: 100%;
 7}
 8
 9body {
10  font-family: 'Montserrat', sans-serif;
11  font-weight: 300;
12  background-image: url("/splash.png");
13  background-color: #220052;
14}
15
16* {
17  margin: 0;
18  padding: 0;
19}
20
21a {
22  color: inherit;
23  text-decoration: underline;
24}
25
26p {
27  margin: 0.83rem 0;
28}
29
30.quote-wrapper {
31  margin-top: 20px;
32}
33
34.quote-wrapper a {
35  text-decoration: none;
36}
37
38.quote-wrapper a:hover {
39  color: #ffffff;
40}
41
42.empty-quote {
43  color: #ffffff;
44}
45
46form {
47  padding: 20px;
48}

在此文件中,您将更新您的应用程序的 CSS 样式在style.css文件中。

您已安装并注册验证器提供商,以便在注册过程中检查用户的输入。您还更新了您的风格表的内容,以便为应用程序添加更多的风格。

步骤 6 – 服务应用程序

在此步骤中,您将服务您的应用程序,并创建一个用户和密码来测试身份验证。

要测试您的应用程序,请从应用程序的 root 目录开始开发服务器,使用以下命令:

1adonis serve --dev

这将启动应用程序在 root .env 文件中定义的端口上,即 3333. 从您的浏览器导航到 http://localhost:3333.

Quote app homepage

主页目前是空的,因为您没有创建任何报价. 点击注册按钮。

Registration page

输入您的详细信息并点击提交按钮完成注册过程.您将被重定向到登录页面. 输入您的电子邮件地址和密码进行身份验证。

Login page

一旦您已验证,请点击 Create Quote 按钮。

Create quote page

输入报价并导航到 ** 查看所有 ** 页面以查看您的报价。

View all quotes page

您已经通过创建和验证用户,然后写报价来测试您的应用程序。

结论

在本教程中,您使用AdonisJs构建了一个Web应用程序,您使用AdonisJs CLI设置了应用程序,并利用CLI创建其他相关文件,如控制器,模型和视图。

您可以使用此框架构建 Web 应用程序,无论其大小和复杂性如何。 请在 GitHub 上下载本项目的源代码(https://github.com/do-community/adonis-quotes-app)。

如果您想探索我们其他一些JavaScript框架教程,请查看以下内容:

Published At
Categories with 技术
comments powered by Disqus