Repository navigation
Version 6.0.0
Ломающие изменения
Модель снова строка таблицы, Record убран. Пятая версия разделила модель
на три класса и оставила поведение строки без места: колонка принадлежала
Record, поэтому всё, что строка умеет сказать о себе, приходилось держать
классом рядом с моделью. Одна таблица — два файла, и чем меньше модель, тем
дороже обходилось разделение.
Модель объявляет таблицу и, прочитанная, держит значения одной строки. Что
строка умеет отвечать — метод модели, рядом с колонками.
class Article extends Model
{
public string $table = 'articles.csv';
public function excerpt(int $words = 30): string
{
return implode(' ', array_slice(explode(' ', $this->text), 0, $words));
}
}
$article = Article::query()->find(1); // Article
$article->excerpt();Найденное пятой версией осталось: строка не несёт условий. where(),
orderBy(), limit() принадлежат Query, поэтому строка не читает таблицу
сама по себе, а связь по-прежнему только метод, объявивший возврат Relation.
find(), first(), get(), cursor(), create() и связи отдают модель.
fresh(), save(), delete(), update(), key(), toArray(),
relationLoaded() и newQuery() — те же методы на модели. RecordMapper стал
RowMapper.
Строка несёт декларацию вместе со значениями, поэтому стоит немного дороже
записи: около 790 байт против 690 на пяти колонках, 377 МБ против 347 на
500 000 строк, прочитанных целиком. Чтение страницы, обход cursor() и подсчёт
не изменились.
Ничего не читается из окружения. resolveCurrentPage() лез в $_GET,
поэтому orm, читающая csv, имела мнение о http, а ответ зависел от того, где
выполняется код: консольная команда, воркер очереди и тест получали то, что
оставил после себя последний запрос. Страницу называет page() или резолвер
приложения, без них имеется в виду первая.
// один раз, в бутстрапе приложения
Pagination::resolvePageUsing(static fn (string $name) => $_GET[$name] ?? 1);links() и встроенный шаблон Bootstrap 5 убраны. Orm везла в комплекте
разметку под css-фреймворк, а рендер вместе с буферизацией вывода жил в
библиотеке данных. Навигацию отдаёт pages() объектами Page, печатает её
приложение:
echo $view->render('pagination', ['pages' => $articles->pages()]);Экранирование ушло туда же, где печать: Page::$url — обычная строка,
экранирует её тот шаблон, который её выводит.
Collection::__toString() убран. Печать коллекции возвращала
Collection@0000..., так что <?= $stories ?> в шаблоне тихо давал хеш вместо
ошибки.
Добавлено
save()вставляет строку, у которой ещё нет ключа, поэтому собранная
руками модель пишется так же, как прочитанная.
$article = new Article();
$article->title = 'Новый заголовок';
$article->save(); // вставлена, ключ выдала таблицаModel::newRow()— строка таблицы с заданными значениями, и
Model::primaryKey()— имя колонки, в которой лежат ключи.Table::primaryKey()— та же колонка, в единственном классе, который
владеет колонками. Раньше правило «ключ — первая колонка» зналиQuery,
TableWriter,RowMapperиModel, каждый сам по себе.
Исправлено
pluck() больше не теряет строки с пустой колонкой. array_column()
спрашивает у объекта __isset(), а он для null отвечает false, поэтому строка
с пустым значением выпадала из результата вместе со своим ключом: таблица
настроек из 43 строк, одна из которых пустая, отдавала 42. Значения читаются
напрямую, пустая колонка остаётся на своём месте со значением null.
Обновление
composer require visavi/motor-orm:^6.0
Требуется PHP 8.5. Формат файлов таблиц не менялся — миграция данных не нужна.