Eloquent ORM - 读取资料

读取表单中的所有资料

接下来的步骤将把 todo 表单中的资料取出展示在 Dashboard 上。

首先看到 TodoController 中的 index 函式

// app\Http\Controllers\TodoController.php

/**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index()
{
    $todos = Todo::get(); //加入这行
}

get() 方法会将 Model 对应的表单中的所有资料取出。

接着就要将读取到的 $todos 资料回传给前端,如果是 API 的话就是将资料回传

// app\Http\Controllers\TodoController.php

/**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index()
{
    $todos = Todo::get();  
    
    return $todos;
}

不过因为这边想将资料显示在 Dashboard 上,所以要回传带有 $todos 资料的 Dashboard 画面

// app\Http\Controllers\TodoController.php

public function index()
{

    $todos = Todo::get();

    return inertia('Dashboard', [
        'todos' => $todos,
    ]);
}

这样 Dashboard 就能将 todos 作为 prop 传入 Dashboard,再显示出来

// resources\js\Pages\Dashboard.js

import { List , ListItem , ListItemText } from "@material-ui/core";


export default function Dashboard(props) {
    
    const { todos } = props; // 取出 todos
    
    // ...

    return (
        <Authenticated
            auth={props.auth}
            errors={props.errors}
            header={
                <h2 className="font-semibold text-xl text-gray-800 leading-tight">
                    Dashboard
                </h2>
            }
        >
            //...
            <Container>
                <form onSubmit={submit}>
                   //...
                </form>
                // 显示 todos 列表
                <List>
                    {todos.map((item) => (
                        <ListItem button>
                            <ListItemText primary={item.name} />
                        </ListItem>
                    ))}
                </List>
            </Container>
        </Authenticated>
    );
}

接着将 /dashboard 路由的 Controller 替换成 TodoController

Route::get('/dashboard', [TodoController::class, 'index'])
->middleware(['auth', 'verified'])->name('dashboard');

这样当进入 Dashboard 画面时就能看到简易的 todo 列表了

inertia.js 局部更新资料

虽然有 todo 清单了不过目前还是静态的资料,只会显示呼叫当下取得的 todo 资料,每当新增 todo 後还得重新整理画面才能看到新增的资料。

这时候就要应用 inertia.js 的局部更新资料功能了,

Inertia.reload({ only: ["todos"] });

Inertia.reload 会重新呼叫目前页面的 url,而用 only 可以指定这次的读取只要更新哪部分的资料。

像这里指定 todos 那就只会更新这个 prop

// app\Http\Controllers\TodoController.php

public function index()
{

    $todos = Todo::get();

    return inertia('Dashboard', [
        'todos' => $todos,  // 对应这里的键值
    ]);
}

所以每当我们新建好 todo 後就呼叫 Inertia.reload

// resources\js\Pages\Dashboard.js

export default function Dashboard(props) {
    // ...
    const submit = (e) => {
        e.preventDefault();
        transform((data) => ({
            name: data.todo,
        }));

        post("/todo", {
            // 新增资料结束後重载 todos
            onFinish: (visit) => {
                Inertia.reload({ only: ["todos"] });
                reset(); //另外顺便清空输入框
            },
        });
    };
    
    //...
}

这样在新增资料後就能马上看到新增的 todo 了。

读取资料应用

前面是利用 get() 方法将所有资料读出来,不过通常我们可不这麽做,而是有条件的读取出需要的资料。

Eloquent 读取资料的函式都是沿用了 Laravel 原生的 Query Builder ,这边列举几个常用的用法

get

没错又是 get ,get 的用法是将"目前条件"下的所有资料取出,前面直接在 Model 下使用 get 所以会将该 Model 对应的所有资料读取出来。

Todo::get() // 读取模型的所有资料

如果有加上其他的筛选条件,就会将符合该条件的所有资料取出

Todo::where('created_at', "<=", now()->subMonth())->get(); // 读取早於一个月前建立的资料

where

基本的搜寻条件函式,是最常用也最多变的一环

基础用法 where( 栏位 , 比较条件 , 目标值 ) ,比较栏位的值与目标值,符合条件的资料用 get 取出

Todo::where('created_at', "<=", now()->subMonth())->get();

通常都用用来比大小或相不相等

where('votes', '>', 100) //大於
where('votes', '>=', 100) //大於等於
where('votes', '<>', 100) //不等於
where('votes', '=', 100)  //等於
where('votes', 100) // 等於的简略写法

也可以用资料库支援的表达式

where('name', 'like', 'T%')

可以串接多个 where ,取交集

// 取年龄小於 60 且大於 35 的使用者
$users = User::where('age', '<', 60)
               ->where('age', '>', 35)
               ->get();

取联集则是使用 orWhere

// 取年龄大於 35 或者名子为 John 的使用者
$users = User::where('age', '>', 35)
               ->orWhere('name', 'John')
               ->get();

可以一次筛选多个条件,取交集

$users = User::where([
    ['status', '=', '1'],
    ['subscribed', '<>', '1'],
])->get();

除了基本 where 还有其他衍伸的 where 函式

// 取介於范围内/外的值
whereBetween('votes', [1, 100])
orWhereBetween('votes', [1, 100])
whereNotBetween('votes', [1, 100])
orWhereNotBetween('votes', [1, 100])

// 取包含 / 不包含在阵列中的值
whereIn('id', [1, 2, 3])
orWhereIn('id', [1, 2, 3])
whereNotIn('id', [1, 2, 3])
orWhereNotIn('id', [1, 2, 3])

// 取栏位是 / 不是 null 的资料
whereNull('deleted_at')
orWhereNull('deleted_at')
whereNotNull('deleted_at')
orWhereNotNull('deleted_at')

// 比较时间
whereDate('created_at', '2016-12-31')
whereDate('created_at', '<' , '2016-12-31')
whereMonth('created_at', '12')
whereDay('created_at', '31')
whereYear('created_at', '2016')
whereTime('created_at', '11:20:45')

//比较两个栏位之间的值
whereColumn('first_name', 'last_name')
whereColumn('updated_at', '>', 'created_at')

where 逻辑组合

可以将条件作为子集合组合出想要的搜寻条件

//名子为 John 且 votes 大於 100 或者 title 为 Admin  

$users = User::where('name', '=', 'John')
               ->where(function ($query) {
                   $query->where('votes', '>', 100)
                         ->orWhere('title', '=', 'Admin');
               })
               ->get();

order

可以用 order 在读取资料的同时将资料排序

$users = User::orderBy('name', 'desc')
               ->get();
asc = 升序
desc = 降序

可以串接多个 order ,会依序用条件排列

$users = User::orderBy('name', 'desc')
               ->orderBy('email', 'asc')
               ->get();

first

first 会取得当下条件排序第一位的资料

$flight = Flight::where('active', 1)->first();

如果没有符合条件的资料,first 只会回传 null,不会报错。

如果想要在没找到对应的资料时报错的话,可以用 firstOrFail()

$flight = Flight::where('active', 1)->firstOrFail();

当抛出的 ModelNotFoundException 未被拦截的话, Laravel 会回传 404 回应,包含对应的错误讯息。

find

find 会搜寻主键值找出一笔资料,通常都是用 id 当主键值来搜寻

$flight = Flight::find(1); // 寻找 id 为 1 的资料

References

Eloquent: Getting Started
Database: Query Builder

<<:  [第十二只羊] 迷雾森林舞会V twitter + devise登入

>>:  Day 12 : 案例分享(4.1) 签核与费用模组 - 费用申请流程

Day27_CSS语法10

border-width(框线宽度) 宽度的设定值有:thin(细)、medium(中)、thick...

Hook 的规则 ( Day18 )

使用 Hook 官方设定需要遵守的两个规则,并提供了一个 linter plugin 来自动化地实行...

Day33 ( 游戏设计 ) 拍西瓜 ( 储存最高分 )

拍西瓜 ( 储存最高分 ) 教学原文参考:拍西瓜 ( 储存最高分 ) 这篇文章会在 Scratch ...

如何让 Grid 显示关联式 SQL 查询的资料 - day22

承前例,接着要完成选取学期後 grid 动态查询更新 vok-orm 资料加载 前端显示多笔资料内容...

Day 8 - 资料储存

在Key-value的结构底下,一张表的储存讯息可以分为三种。分别是row、index、表的元信息。...