在本系列的上一节中,您为LinkList
和Link
模型之间的关系设置了两种模型. 在本节中,您将学习如何使用Eloquent模型在数据库中插入链接和列表。
使用 ORM 系统的最大优点之一是能够将数据库表中的行作为代码库中的对象进行操纵。 与其他 ORM 一样,Eloquent 和其它 ORM 一样,对象本身提供了可以用于将其持续到数据库的方法,从而节省了您写 SQL 陈述和手动管理表中的数据的工作。
在 Laravel Eloquent 中使用一对多关系时,您有几种不同的选择来保存相关模型。在大多数情况下,您需要先设置代表关系的 一侧的模型,在这个演示中是LinkList
模型,然后将其保存到数据库中。
然而,在创建新命令以插入列表之前,您应该更新现有的link:new
命令以支持列表功能。
在您的代码编辑器中打开以下文件:
1app/Console/Commands/LinkNew.php
你会看到这样的代码:
1[label app/Console/Commands/LinkNew.php]
2<?php
3
4namespace App\Console\Commands;
5
6use App\Models\Link;
7use Illuminate\Console\Command;
8use Illuminate\Support\Facades\DB;
9
10class LinkNew extends Command
11{
12 /**
13 * The name and signature of the console command.
14 *
15 * @var string
16 */
17 protected $signature = 'link:new';
18
19 /**
20 * The console command description.
21 *
22 * @var string
23 */
24 protected $description = 'Create a New Link';
25
26 /**
27 * Create a new command instance.
28 *
29 * @return void
30 */
31 public function __construct()
32 {
33 parent::__construct();
34 }
35
36 /**
37 * Execute the console command.
38 *
39 * @return int
40 */
41 public function handle()
42 {
43 $url = $this->ask('Link URL:');
44
45 if (!filter_var($url, FILTER_VALIDATE_URL)) {
46 $this->error("Invalid URL. Exiting...");
47 return 1;
48 }
49
50 $description = $this->ask('Link Description:');
51
52 $this->info("New Link:");
53 $this->info($url . ' - ' . $description);
54
55 if ($this->confirm('Is this information correct?')) {
56 $link = new Link();
57 $link->url = $url;
58 $link->description = $description;
59 $link->save();
60
61 $this->info("Saved.");
62 }
63
64 return 0;
65 }
66}
handle()
方法是指指令执行其程序的地方,这就是它所做的:
- 「ask()」方法,通过原始类「Illuminate\Console\Command」提供,是一种方法,用来从命令行中获取用户的输入。这将提示用户进行链接,并验证输入以确保它是有效的 URL.
- 脚本然后请求可选的描述
3.一旦获得了 url和 description的值,脚本将请求使用「confirm()」方法进行确认,通过原始类「Illuminate\Console\Command
」提供。
<$>[info]
关于返回值的注意事项:在运行在bash
的命令行应用程序中,非零返回值被用来表示应用程序错误地退出,而0
意味着应用程序成功地退出。
如果您现在运行link:new
命令,它将在完成之前被打破,因为数据库预计每个链接将连接到一个列表,您需要让用户选择哪个列表将包含链接,使用默认列表,如果没有由用户提供。
下面的代码会要求用户指定一个列表或将其留在空中,以使用默认列表。然后,它会尝试使用指定的 slug 找到列表或创建一个新列表,如果列表尚不存在。 为了获取用户提供的列表,此代码使用firstWhere
方法以基于其 slug字段找到列表。
将您的LinkNew
命令类中的当前内容替换为:
1[label app/Console/Commands/LinkNew.php]
2<?php
3
4namespace App\Console\Commands;
5
6use App\Models\Link;
7use App\Models\LinkList;
8use Illuminate\Console\Command;
9use Illuminate\Support\Facades\DB;
10
11class LinkNew extends Command
12{
13 /**
14 * The name and signature of the console command.
15 *
16 * @var string
17 */
18 protected $signature = 'link:new';
19
20 /**
21 * The console command description.
22 *
23 * @var string
24 */
25 protected $description = 'Create a New Link';
26
27 /**
28 * Create a new command instance.
29 *
30 * @return void
31 */
32 public function __construct()
33 {
34 parent::__construct();
35 }
36
37 /**
38 * Execute the console command.
39 *
40 * @return int
41 */
42 public function handle()
43 {
44 $url = $this->ask('Link URL');
45
46 if (!filter_var($url, FILTER_VALIDATE_URL)) {
47 $this->error("Invalid URL. Exiting...");
48 return 1;
49 }
50
51 $description = $this->ask('Link Description');
52 $list_name = $this->ask('Link List (leave blank to use default)') ?? "default";
53
54 $this->info("New Link:");
55 $this->info($url . ' - ' . $description);
56 $this->info("Listed in: " . $list_name);
57
58 if ($this->confirm('Is this information correct?')) {
59 $list = LinkList::firstWhere('slug', $list_name);
60 if (!$list) {
61 $list = new LinkList();
62 $list->title = $list_name;
63 $list->slug = $list_name;
64 $list->save();
65 }
66
67 $link = new Link();
68 $link->url = $url;
69 $link->description = $description;
70 $list->links()->save($link);
71
72 $this->info("Saved.");
73 }
74
75 return 0;
76 }
77}
完成后,保存并关闭文件,然后运行命令:
1docker-compose exec app php artisan link:new
您将被要求提供 URL、描述和列表名称,如果您不想将此链接保存到默认列表中。
一旦您保存了新链接,如果运行link:show
命令,您应该看到新链接添加到结果中。
在您的代码编辑器中打开app/Console/Commands/LinkShow.php
文件:
1app/Console/Commands/LinkShow.php
现在的课堂应该是这样的:
1[label app/Console/Commands/LinkShow.php]
2<?php
3
4namespace App\Console\Commands;
5
6use App\Models\Link;
7use Illuminate\Console\Command;
8
9class LinkShow extends Command
10{
11 /**
12 * The name and signature of the console command.
13 *
14 * @var string
15 */
16 protected $signature = 'link:show';
17
18 /**
19 * The console command description.
20 *
21 * @var string
22 */
23 protected $description = 'List links saved in the database';
24
25 /**
26 * Create a new command instance.
27 *
28 * @return void
29 */
30 public function __construct()
31 {
32 parent::__construct();
33 }
34
35 /**
36 * Execute the console command.
37 *
38 * @return int
39 */
40 public function handle()
41 {
42 $headers = [ 'id', 'url', 'description' ];
43 $links = Link::all(['id', 'url', 'description'])->toArray();
44 $this->table($headers, $links);
45
46 return 0;
47 }
48}
您将看到当前的 handle()
方法正在采集一定数量的字段并将结果转换为一个数组. 默认情况下,结果来自 Eloquent 作为一个 Eloquent 集合,所以这个函数将它们转换为一个数组,以便在 table()
方法中使用这些数据。
您需要更改此代码以获取完整的链接
对象,包括来自数据库的相关对象。 若要创建适用于table()
方法的数组,您可以重复通过Link::all()
返回的结果集合。
在app/Console/Commands/LinkShow.php
文件中的当前内容以以下代码替换:
1[label app/Console/Commands/LinkShow.php]
2<?php
3
4namespace App\Console\Commands;
5
6use App\Models\Link;
7use Illuminate\Console\Command;
8
9class LinkShow extends Command
10{
11 /**
12 * The name and signature of the console command.
13 *
14 * @var string
15 */
16 protected $signature = 'link:show';
17
18 /**
19 * The console command description.
20 *
21 * @var string
22 */
23 protected $description = 'List links saved in the database';
24
25 /**
26 * Create a new command instance.
27 *
28 * @return void
29 */
30 public function __construct()
31 {
32 parent::__construct();
33 }
34
35 /**
36 * Execute the console command.
37 *
38 * @return int
39 */
40 public function handle()
41 {
42 $headers = [ 'id', 'url', 'list', 'description' ];
43 $links = Link::all();
44
45 $table_rows = [];
46 foreach ($links as $link) {
47 $table_rows[] = [ $link->id, $link->url, $link->link_list->slug, $link->description ];
48 }
49
50 $this->table($headers, $table_rows);
51
52 return 0;
53 }
54}
现在,如果运行链接:显示
方法,您将看到一个额外的列表列表:
1[secondary_label Output]
2+----+-----------------------------------------------------------------------------------------+-----------+--------------------------------------+
3| id | url | list | description |
4+----+-----------------------------------------------------------------------------------------+-----------+--------------------------------------+
5| 1 | https://digitalocean.com | default | DigitalOcean Website |
6| 2 | https://digitalocean.com/community/tutorials | tutorials | DO Tutorials |
7| 3 | https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-20-04 | tutorials | Initial server setup on ubuntu 20.04 |
8+----+-----------------------------------------------------------------------------------------+-----------+--------------------------------------+
在本教程系列后面,您将更新前端和主要路由代码,以显示列表中的链接. 目前,您将使用命令行添加,迁移和验证数据库和模型的更改。
本系列的下一个教程将展示使用 Eloquent 模型在数据库中插入新记录的另一种方法,这次通过使用 数据库种子。