资讯专栏INFORMATION COLUMN

Laravel 5.4 入门系列 4. 任务列表显示(2)

banana_pi / 2060人阅读

摘要:同时,传入参数,即已存在的查询。因此,更为常见的做法是在控制器中处理路由请求。

这一节,我们进一步完善上一节创建的任务列表。主要知识点:

Eloquent Model

控制器

路由模型绑定

Eloquent Model 新增迁移

首先,我们为数据库表 tasks 新增一个字段 completed,用来表示任务是否完成:

$ php artisan make:migration add_completed_to_tasks_table --table=tasks

这次,我们使用 --table 指定已存在的表。接着添加具体字段:

// /database/migrations/2017_04_11_060132_add_completed_to_tasks_table.php
public function up()
{
    Schema::table("tasks", function (Blueprint $table) {
        $table->boolean("completed")->default(0);
    });
}

public function down()
{
    Schema::table("tasks", function (Blueprint $table) {
        $table->dropColumn("completed");
    });
}

执行迁移:

$ php artisan migrate

如果我们想要回滚本次迁移,可以执行:

$ php artisan migrate:rollback

将会执行迁移任务的 down() 函数:

上手 Eloquent Model

上一节,我们使用 DB 来操纵数据库,在 Laravel 中,也叫做查询构造器。实际上,Laravel 提供了更为强大的用来与数据库交互的工具:Eloquent Model

首先,我们来创建一个与 tasks 表格对应的 Model:

$ php artisan make:model Task

现在,我们就可以使用 Eloquent 了,启动控制台:

$ php artisan tinker

可以先对 Task 类实例化,然后再进行各种操作:

>>> $task = new AppTask;  # 新建一个 Task 实例

新建任务:

>>> $task->name = "新的任务"
>>> $task->completed = 1
>>> $task->save()  # 保存新实例

>>> $task 
=> AppTask {#674
     name: "新的任务",
     completed: 1,
     updated_at: "2017-04-11 06:14:10",
     created_at: "2017-04-11 06:14:10",
     id: 4,
   }

查询:

>>> $task->all()->toJson();  # 获取数据并转化为 json 格式
>>> $task->where("completed",1)->get(); # 查看完成的任务
>>> $task->pluck("name")->first(); # 获取第一条记录的 name 字段

也可以不实例,直接调用「门面」方法来操作:

>>> AppTask::first();  # 获取第一条记录
>>> AppTask::latest()->get(); # 按先后顺序显示记录
自定义方法

刚才的例子中,有一行是用来查询已完成的任务的:

>>> $task->where("completed",1)->get();

该查询在很多地方都有可能要用到,为了避免重复工作,我们将其封装到 Model 中:

// /app/Task.php
class Task extends Model
{    
    public function completed()
    {
        return static::where("completed",1)->get();
    }

     public function unCompleted()
    {
        return static::where("completed",0)->get();
    }
}

我们定义了 completed()unCompleted() 方法分别获取已完成和未完成的任务。现在,需要重新启动 tinker

>>> $task = new AppTask;
>>> $task->completed();
>>> $task->uncompleted()->pluck("name");

那么,我们是否可以直接使用 `Task::completed()呢?当然可以,不过需要把方法改成静态的,因为静态方法可以通过类和实例访问:

 public static function completed()
{
    return static::where("completed",1)->get();
}

 public static function unCompleted()
{
    return static::where("completed",1)->get();
}

这样就可以通过类直接访问了,依旧要重启 tinker 才能生效

$ php artisan tinker
>>> AppTask::completed()
>>> AppTask::unComplete()

对于上述的方法,Laravel 提供了更为便利的方式实现,叫做范围查询:

public function scopeCompleted($query)
{
    return $query->where("completed",1);
}

 public function scopeUnCompleted($query)
{
    return $query->where("completed",0);
}

使用范围查询,只需要在我们的方法前面加上 scope 就行,这样就不用去定义静态方法。同时,传入 $query 参数,即已存在的查询。我们只需要在此基础上添加自己想要的查询就可以了。现在,可以方便的使用了:

$ php artisan tinker
>>> use AppTask;
>>> Task::completed()->get();
>>> Task::unCompleted()->pluck("name")

经过对 Eloquent 的初步学习之后,我们可以将之前的 DB 查询换成 Eloquent 的:

// /routes/web.php
completed()->get();
    $unCompletedTasks = Task::latest()->unCompleted()->get();
    return view("tasks/index",compact("completedTasks","unCompletedTasks"));
});

Route::get("tasks/{task}", function($id) {
    $task = Task::findorFail($id);
    return view("tasks/show",compact("task"));
});

对应的视图文件也稍微修改下:

// /resources/views/tasks/index.blade.php

    

任务列表

未完成

已完成

控制器

之前,我们都是直接在路由处理请求,看上去好像没什么问题。但是,如果当网站规模大起来之后,将路由和业务处理放在一起会变得难以维护。因此,更为常见的做法是在控制器中处理路由请求。

创建控制器

首先是控制器的创建:

$ php artisan make:controller TasksController

这样就创建了一个空白的控制器了。

在控制器中处理请求

接下来,我们就可以在控制器中定义不同的方法来处理路由请求了。先在路由中指定请求由哪个控制器的方法处理:

Route::get("tasks","TasksController@index");
Route::get("tasks/{task}","TasksController@show");

控制器里面可以把刚才路由的方法拷贝进来:

// /app/Http/Controllers/TasksController.php
completed()->get();
        $unCompletedTasks = Task::latest()->unCompleted()->get();
        return view("tasks/index",compact("completedTasks","unCompletedTasks"));
    }

    public function show($task)
    {
        $task = Task::findorFail($task);
        return view("tasks/show",compact("task"));
    }
}
路由模型绑定 自动路由模型绑定

刚才的 show 方法,可以进一步简写成:

// /app/Http/Controllers/TasksController.php
public function show(Task $task)
{
    return view("tasks/show",compact("task"));
}

功能完全一样,如果觉得好奇,可以打印出 $task

// /app/Http/Controllers/TasksController.php
public function show(Task $task)
{    
    dd($task);
}

你会发现,此时的 $task 已经不是参数值了,而是从数据库返回的对应实例。也就是说,我们为 $task 添加了类型提示 Task 之后,Laravel 自动帮我们进行了查询。这就叫做自动路由模型绑定。

手动路由模型绑定

当然,我们也可以手动进行绑定!比如我只想要显示完成的任务:

// /app/Providers/RouteServiceProvider.php
public function boot()
{   
    parent::boot();
    Route::bind("task",function($task){
        return AppTask::completed()->findOrFail($task);
    });
}

然后访问未完成的任务,比如 task/1,就会报错。


参考:

PHP: Static(静态)关键字 - Manual

Eloquent: 入门 | Laravel 5.4 中文文档

Laravel 5.2 Error "Missing argument 1 for IlluminateAuthAuthManager::createDriver()"

Laravel HTTP 路由功能 | Laravel 5.4 中文文档

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22707.html

相关文章

  • Laravel 5.4 入门系列 3. 任务列表显示

    摘要:熟悉了路由与视图的基本操作之后,我们来让视图显示一个任务列表吧。创建迁移现在,我们就可以创建一个用来生成任务表的迁移了。 熟悉了路由与视图的基本操作之后,我们来让视图显示一个任务列表吧。主要知识点: 数据迁移 查询构造器 数据库 创建数据库 首先创建一个数据库: $ mysql -uroot -p mysql> create database laratasks; 数据库配置 La...

    SunZhaopeng 评论0 收藏0
  • Laravel 5.4 入门系列 7. 文章的显示

    摘要:为的辅助方法,用于截取字符串的前个字符,然后返回前个字符加的格式。显示某篇文章显示某篇文章的比较简单,路由注意要放在下面,假如这样那么,我们访问的时候,会被当成是的查询参数。 文章的显示功能比较简单,分为两部分: 文章列表 具体的某篇文章 显示文章列表 路由之前已经定义好: Route::get(/posts,PostsController@index); 控制器: public ...

    kuangcaibao 评论0 收藏0
  • Laravel 5.4 入门系列 5. 博客通用布局

    摘要:接下来执行迁移即可通用布局通用布局首先是博客首页,定义路由控制器视图博客首页访问下网站根目录,显示博客首页,框架基本搭建完成了。首先是通用布局通用布局里面除了使用之外,还使用了,用于加载其他模板。 5. 博客的通用布局 初始化 创建控制器、模型、迁移 博客的核心是文章,可以先来实现和文章有关的功能,根据前几节的介绍可知,我们至少需要创建这几类: PostsController:控制器...

    xuweijian 评论0 收藏0
  • Laravel 5.4 入门系列 9. 注册与登录,用户关联

    摘要:本节将实现文章评论与用户关联的功能。关系定义首先修改与表,增加字段增加全部回滚并重新执行迁移添加用户表与文章表评论表的一对多关系添加文章评论表与用户表的多对一关系同时,评论表的字段增加。同时,我们还自定义了返回的错误信息。 本节将实现文章、评论与用户关联的功能。 关系定义 首先修改 posts 与 comments 表,增加 user_id 字段 /database/migratio...

    smallStone 评论0 收藏0
  • Laravel 5.4 入门系列 13. 终篇: 小白也能看懂的 Laravel 核心概念讲解

    摘要:但是服务通常由服务提供者来管理的。小结通过上述的例子,基本上可以理解服务容器和服务提供者的使用。懂得了服务容器和服务提供者,理解门面也就不难了。 自动依赖注入 什么是依赖注入,用大白话将通过类型提示的方式向函数传递参数。 实例 1 首先,定义一个类: /routes/web.php class Bar {} 假如我们在其他地方要使用到 Bar 提供的功能(服务),怎么办,直接传入参数即...

    BenCHou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<