Skip to the content
OrielDocs
0.1.0-alpha.10GitHub

Models

Eloquent: observers

Models dispatch events as they are created, updated, deleted and restored. Listen for them with a closure, or group the listeners for one model in an observer class.

Introduction#

A model dispatches these events, each with the model:

EventWhen
retrievedA model was read from the database
creating, createdA new model is about to be saved for the first time, and was
updating, updatedA model that exists is about to be saved with changes, and was
saving, savedA model is about to be saved, new or not, changed or not, and was
deleting, deletedA model is about to be deleted, or soft-deleted, and was
restoring, restoredA soft-deleted model is about to be restored, and was
forceDeleting, forceDeletedA soft-deleted model is about to be deleted for good, and was

Creating a model dispatches saving, creating, created, then saved; updating one dispatches saving, updating, updated, then saved. Saving a model with no changes dispatches only saving and saved.

A listener of a -ing event that returns false stops the operation: the model isn't saved, deleted or restored.

Using closures#

Register a closure for an event in the model's static booted(), with the method named after the event:

app/Models/User.ts
import { Model } from '@orieljs/framework'export class User extends Model {  /** The "booted" method of the model. */  static override booted(): void {    this.created((user) => {      // ...    })  }}

booted() runs once, the first time the model is used in your app.

Observers#

Defining observers#

An observer is a class whose methods are named after the events they handle. make:observer writes one in app/Observers, with created(), updated() and deleted() methods; give their parameter your model's type:

Terminal
node oriel make:observer UserObserver
app/Observers/UserObserver.ts
import type { User } from '../Models/User'export class UserObserver {  /** Handle the User "created" event. */  created(user: User): void {    // ...  }  /** Handle the User "updated" event. */  updated(user: User): void {    // ...  }  /** Handle the User "deleted" event. */  deleted(user: User): void {    // ...  }}

Register it with the model's observe(), in a service provider's boot():

app/Providers/AppServiceProvider.ts
import { ServiceProvider } from '@orieljs/framework'import { User } from '../Models/User'import { UserObserver } from '../Observers/UserObserver'export class AppServiceProvider extends ServiceProvider {  override boot(): void {    User.observe(UserObserver)  }}

Every method named after an event is registered. Oriel makes the observer through your app's container, so it can take a service with inject(); an instance works too: User.observe(new UserObserver()).

A -ing method that returns false cancels the operation, as a closure does:

app/Observers/PostObserver.ts
import { Str } from '@orieljs/framework'import type { Post } from '../Models/Post'export class PostObserver {  /** Give a new post its slug. */  creating(post: Post): void {    post.slug = Str.slug(post.title)  }  /** A published post can't be deleted. */  deleting(post: Post): boolean {    return post.published_at === null  }}

Event names#

A model event is dispatched as eloquent.<event>: <Model>, such as eloquent.created: User, so you can also listen for it with Event.listen(). Laravel uses the model's full class name; Oriel uses the class's name.

Muting events#

Model.withoutEvents() runs a function with model events off, for the code it runs:

const user = await Model.withoutEvents(() => User.findOrFail(1))

saveQuietly() and deleteQuietly() save or delete one model without events:

const user = await User.findOrFail(1)user.name = 'Victoria Faith'await user.saveQuietly()

Privacy policy ·

esc