Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Модели 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 значение не попадёт в базу. Для каждого столбца таблицы, который нужен в коде, объявляйте свойство с декоратором.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.