← Предыдущая · Назад к README · Следующая →
Eloquent
FeedObserver::saving() выполняется при каждом вызове методов модели create(), update() или save() с включёнными событиями. После PR #335 он присваивает $feed->slug = $feed->title, только если $feed->isDirty('slug') возвращает false. SlugCast применяет Str::slug() как к автоматически созданным, так и к заданным вручную slug. Например, Products превращается в products.
Явно изменённый slug сохраняется при текущем сохранении, в том числе при одновременном изменении title. Это не закрепляет пользовательский slug навсегда: при следующем обычном сохранении неизменённый slug пересчитывается из title, даже если название не изменилось. Присваивание того же slug или значения, которое нормализуется в текущий slug, не считается изменением.
Observer читает текущее свойство title с учётом современных и классических accessors и уже применённых сеттеров. Это не сырое сохранённое название и не обязательно окончательное значение в базе данных. Accessor, возвращающий Display: Stored: Product Catalog, даёт display-stored-product-catalog. Вынесите форматирование для отображения в отдельный accessor, если оно не должно влиять на slug.
saveQuietly() и сохранение внутри withoutEvents() пропускают observer. При таком изменении title прежний slug сохраняется, если приложение не задаёт его явно. Если события нужны, используйте обычное сохранение. Для тихого сохранения с тем же правилом, что у observer:
use DragonCode\LaravelFeed\Models\Feed;
$feed = Feed::query()->findOrFail(42);
$feed->title = 'New Title';
$feed->slug = $feed->title;
$feed->saveQuietly();
Если последующий обработчик saving либо обработчик creating или updating меняет title, пакет не пересчитывает slug повторно. Предпочтительно задавать название до сохранения или через мутатор. Если менять его нужно в позднем обработчике, сразу после изменения присвойте $feed->slug = $feed->title в том же обработчике; не вызывайте save() рекурсивно. Проверяйте порядок обработчиков тестами приложения.
При сохранении частично выбранной модели без явно изменённого slug загрузите title и все поля, необходимые его accessor. Отсутствие title не отключает генерацию slug. Массовые вставки и обновления Query Builder не запускают observer; явно поддерживайте оба значения при таких записях. В пользовательских моделях сохраняйте унаследованные observer и casts.
Для выбора отдельных фидов и запуска по расписанию сохраняйте различные непустые slug. При вычислении slug из названий выбирайте названия, которые нормализуются в различные непустые значения. Пустой сохранённый slug нельзя выбрать. Если slug совпадает у нескольких неудалённых записей, поиск выбрасывает Illuminate\Database\MultipleRecordsFoundException; суффиксы автоматически не добавляются.
Пользовательская модель регистрации фида
Задайте для feeds.model модель приложения, если записям регистрации фидов нужны дополнительные столбцы, преобразования, связи или методы. Пользовательская модель должна расширять DragonCode\LaravelFeed\Models\Feed.
namespace App\Models;
use DragonCode\LaravelFeed\Models\Feed as BaseFeed;
class Feed extends BaseFeed
{
protected $fillable = [
'slug',
'class',
'title',
'expression',
'is_active',
'last_activity',
'is_foo',
'is_bar',
];
protected function casts(): array
{
return [
...parent::casts(),
'is_foo' => 'boolean',
'is_bar' => 'boolean',
];
}
}
Зарегистрируйте модель в config/feeds.php:
'model' => App\Models\Feed::class,
Добавьте пользовательские столбцы в таблицу фидов через миграцию приложения. Оставьте в $fillable каждый атрибут, разрешённый для массового присваивания.
FeedQuery использует настроенную модель для создания, поиска, получения списка, обновления, удаления и восстановления. При создании записи передавайте специфичные для приложения значения через extra. Они применяются последними и могут переопределить аргументы метода:
$feed = app(FeedQuery::class)->create(
class: SomeFeed::class,
title: 'Some',
expression: '0 */12 * * *',
extra: [
'slug' => 'Custom Some',
'is_foo' => true,
'is_bar' => true,
]
);
Так создаётся регистрация со slug custom-some. Методы модели create() и update() также принимают явный slug; одновременное обновление title и slug сохраняет изменённый slug при текущем сохранении.
Модель приложения также может использовать обычный API Eloquent:
use App\Models\Feed;
$feed = Feed::create([
'class' => SomeFeed::class,
'title' => 'Some',
'expression' => '0 */12 * * *',
'is_active' => true,
'is_foo' => true,
'is_bar' => true,
]);
Настроенная модель определяется во время выполнения. Статический анализ считает результат FeedQuery::create() базовой моделью пакета. Если для специфичных свойств приложения нужно автодополнение, используйте App\Models\Feed::create() или явный локальный тип.
Размер блока
Запросы к базе данных используют блоки, которые по умолчанию содержат 1000 элементов. Размер можно изменить, переопределив метод chunkSize:
use DragonCode\LaravelFeed\Feeds\Feed;
class UserFeed extends Feed
{
public function chunkSize(): int
{
return 500;
}
}