Модели Lucid
Модель — это класс, который соответствует таблице базы данных, а каждый объект этого класса — одной строке таблицы. Вместо SQL вы вызываете методы модели: Post.find(1), post.save(). Это аналог моделей Eloquent в Laravel, только столбцы перечисляются в классе явно.
Создание модели
node ace make:model PostПоявится файл app/models/post.ts. Модель Post по умолчанию работает с таблицей posts. С флагом -m команда создаст и миграцию: node ace make:model Comment -m.
Описание столбцов
Каждый столбец таблицы объявляется свойством с декоратором @column:
// app/models/post.ts
import { DateTime } from 'luxon'
import { BaseModel, column } from '@adonisjs/lucid/orm'
export default class Post extends BaseModel {
@column({ isPrimary: true })
declare id: number
@column()
declare title: string
@column()
declare body: string
@column()
declare isPublished: boolean
@column.dateTime({ autoCreate: true })
declare createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
declare updatedAt: DateTime
}Свойства пишутся в camelCase, а Lucid сам сопоставляет их со столбцами в snake_case: isPublished — это is_published. Даты приходят объектами DateTime из библиотеки Luxon. autoCreate и autoUpdate заполняют время создания и изменения.
Создание записи
// app/controllers/posts_controller.ts
import Post from '#models/post'
const post = await Post.create({
title: 'Первая статья',
body: 'Текст статьи',
})
console.log(post.id)create вставляет строку в таблицу и возвращает модель с заполненным id. Тот же результат даёт new Post(), присваивание свойств и await post.save().
Чтение
// app/controllers/posts_controller.ts
const posts = await Post.all()
const post = await Post.find(1)
const bySlug = await Post.findBy('slug', 'hello')all возвращает массив моделей, find — модель с указанным id или null, findBy — первую запись с нужным значением столбца.
Изменение и удаление
// app/controllers/posts_controller.ts
const post = await Post.findOrFail(1)
post.merge({ title: 'Новый заголовок' })
await post.save()
await post.delete()merge присваивает несколько свойств сразу, save записывает изменения в базу, delete удаляет строку.
Модель в контроллере и шаблоне
// app/controllers/posts_controller.ts
async show({ params, view }: HttpContext) {
const post = await Post.findOrFail(params.id)
return view.render('pages/posts/show', { post })
}{{-- resources/views/pages/posts/show.edge --}}
@layout({ title: post.title })
<h1>{{ post.title }}</h1>
<p>{{ post.createdAt.toFormat('dd.MM.yyyy') }}</p>
<div>{{ post.body }}</div>
@endОткройте /posts/1 — появится статья с датой. Если записи нет, findOrFail выбросит исключение и посетитель увидит страницу 404.
Частая ошибка
Если в модели забыть @column у свойства, Lucid не узнает о столбце: при чтении свойство будет undefined, а при create значение не попадёт в базу. Для каждого столбца таблицы, который нужен в коде, объявляйте свойство с декоратором.