Skip to content

Модели данных

Модели — это основа работы с данными в Kodzero SDK. Они предоставляют объектно-ориентированный интерфейс для взаимодействия с коллекциями вашего бэкенда в стиле Active Record.

Создание модели

Базовый синтаксис

typescript
const Model = kodzero.createModel({
  collection: 'collection_name'
})

С TypeScript типами

typescript
// Определяем интерфейс данных
interface User {
  _id: string | null
  name: string
  email: string
  age?: number
  createdAt?: Date
}

// Создаём типизированную модель
const User = kodzero.createModel<User>({
  collection: 'users'
})

Со схемой валидации

typescript
const userSchema = {
  _id: { type: String },
  name: { type: String, required: true },
  email: { type: String, required: true },
  age: { type: Number }
}

const User = kodzero.createModel<User>({
  collection: 'users',
  schema: userSchema
})

Работа с экземплярами

Создание экземпляра

typescript
// Создание нового документа
const user = new User({
  _id: null,  // null для новых документов
  name: 'Иван Иванов',
  email: 'ivan@example.com'
})

Получение данных

typescript
// Метод data() возвращает текущие данные модели
const userData = user.data()

console.log(userData.name)   // 'Иван Иванов'
console.log(userData.email)  // 'ivan@example.com'
console.log(userData._id)    // null (пока не сохранён)

Изменение данных

Установка отдельного поля

typescript
user.set('name', 'Пётр Петров')

Установка нескольких полей

typescript
user.set({
  name: 'Пётр Петров',
  age: 30
})

Работа с вложенными полями

typescript
interface Profile {
  _id: string | null
  user: {
    name: string
    contact: {
      email: string
      phone?: string
    }
  }
}

const profile = new Profile({
  _id: null,
  user: {
    name: 'Иван',
    contact: {
      email: 'ivan@example.com'
    }
  }
})

// Установка вложенного поля через точечную нотацию
profile.set('user.contact.phone', '+7-999-123-4567')

// Множественная установка вложенных полей
profile.set({
  'user.name': 'Пётр',
  'user.contact.email': 'petr@example.com'
})

Методы экземпляра

save()

Сохраняет документ. Автоматически определяет, нужно ли создать новый документ или обновить существующий:

typescript
const user = new User({
  _id: null,
  name: 'Иван'
})

// Создаёт новый документ
await user.save()
console.log(user.data()._id) // 'generated_id'

// Изменяем данные
user.set('name', 'Иван Иванов')

// Обновляет существующий документ
await user.save()

create()

Явно создаёт новый документ:

typescript
await user.create()

update()

Явно обновляет существующий документ:

typescript
await user.update()

Требуется _id

Метод update() требует наличия _id. Если _id отсутствует, будет выброшена ошибка.

delete()

Удаляет документ из базы данных:

typescript
const deleted = await user.delete()

if (deleted) {
  console.log('Документ удалён')
}

validate()

Валидирует данные по схеме (если схема была указана при создании модели):

typescript
const result = user.validate()

if (result.ok) {
  console.log('Данные корректны')
} else {
  console.log('Ошибки:', result.joinErrors())
}

Статические методы

Статические методы позволяют работать с коллекцией напрямую, без создания экземпляра.

get(id)

Получает документ по ID и возвращает экземпляр модели:

typescript
const user = await User.get('user_id')

// user — это экземпляр модели с методами
user.set('name', 'Новое имя')
await user.save()

find(id)

Получает документ по ID и возвращает простой объект:

typescript
const userData = await User.find('user_id')

// userData — это просто объект с данными
console.log(userData.name)

findMany(options?)

Получает список документов:

typescript
const users = await User.findMany({
  page: 1,
  perPage: 25,
  search: 'Иван',
  sort: '-createdAt',  // минус означает по убыванию
  fields: ['name', 'email']  // только указанные поля
})

Параметры:

ПараметрТипОписание
pagenumberНомер страницы (начиная с 1)
perPagenumberКоличество документов на страницу
searchstringПоисковый запрос
sortstringПоле для сортировки (префикс - для убывания)
fieldsstring[]Список полей для возврата

findManyPaginated(options?, page?, perPage?)

Получает список документов с информацией о пагинации:

typescript
const result = await User.findManyPaginated({}, 1, 25)

console.log(result.data)       // массив документов
console.log(result.state.page) // текущая страница
console.log(result.state.total) // общее количество документов

Подробнее см. Пагинация.

create(data)

Создаёт новый документ:

typescript
const newUser = await User.create({
  name: 'Иван',
  email: 'ivan@example.com'
})

console.log(newUser._id) // 'generated_id'

update(id, data)

Обновляет документ по ID:

typescript
const updatedUser = await User.update('user_id', {
  name: 'Новое имя'
})

delete(id)

Удаляет документ по ID:

typescript
const deleted = await User.delete('user_id')
// deleted: true

Пакетные операции

createMany(records)

Создаёт несколько документов за один запрос:

typescript
const newUsers = await User.createMany([
  { name: 'Иван', email: 'ivan@example.com' },
  { name: 'Пётр', email: 'petr@example.com' },
  { name: 'Мария', email: 'maria@example.com' }
])

updateMany(updates)

Обновляет несколько документов за один запрос:

typescript
const updated = await User.updateMany([
  { _id: 'id1', name: 'Новое имя 1' },
  { _id: 'id2', name: 'Новое имя 2' }
])

Требуется _id

Каждый объект в массиве должен содержать поле _id.

deleteMany(ids)

Удаляет несколько документов за один запрос:

typescript
const results = await User.deleteMany(['id1', 'id2', 'id3'])

// results: { 'id1': true, 'id2': true, 'id3': true }

Полный пример

typescript
import Kodzero from 'kodzero-front-sdk-alfa'

const kodzero = new Kodzero({
  host: 'https://api.example.com',
  authCollection: 'auth'
})

// Определяем интерфейс
interface Product {
  _id: string | null
  name: string
  price: number
  category: string
  inStock: boolean
}

// Создаём модель со схемой
const productSchema = {
  _id: { type: String },
  name: { type: String, required: true },
  price: { type: Number, required: true },
  category: { type: String },
  inStock: { type: Boolean }
}

const Product = kodzero.createModel<Product>({
  collection: 'products',
  schema: productSchema
})

// === Создание ===
const laptop = new Product({
  _id: null,
  name: 'Ноутбук MacBook Pro',
  price: 150000,
  category: 'Электроника',
  inStock: true
})

// Валидация перед сохранением
const validation = laptop.validate()
if (!validation.ok) {
  console.error(validation.joinErrors())
} else {
  await laptop.save()
}

// === Чтение ===
// Получить один товар как экземпляр
const product = await Product.get('product_id')
console.log(product.data().name)

// Получить список товаров
const products = await Product.findMany({
  page: 1,
  perPage: 10,
  sort: '-price',  // по убыванию цены
  search: 'ноутбук'
})

// === Обновление ===
product.set('price', 140000)
await product.update()

// Или обновить напрямую
await Product.update('product_id', { price: 140000 })

// === Удаление ===
await product.delete()

// Или удалить напрямую
await Product.delete('product_id')

// === Пакетные операции ===
// Массовое создание
await Product.createMany([
  { name: 'Товар 1', price: 100, category: 'Категория 1', inStock: true },
  { name: 'Товар 2', price: 200, category: 'Категория 2', inStock: false }
])

// Массовое удаление
await Product.deleteMany(['id1', 'id2', 'id3'])

Следующие шаги

Опубликовано под лицензией ISC.