Skip to content

Convenience methods, soft deletes, and hiding sensitive data from JSON

Compare
Choose a tag to compare
@mdwheele mdwheele released this 18 Sep 21:39
· 14 commits to master since this release
daa9b86

This release adds several convenience methods to Model for retrieving model instances:

  • Model.firstOrCreate({ ... }) finds the first record with matching attributes. If no record matches the attributes given, one is inserted and the model instance is returned.
  • Model.findOrFail(id) retrieves a model instance by primary key. If the record does not exist, it throws an Error.
  • Model.all() returns all instances.

Additionally, YORM now supports "soft deletes", which are a recoverable form of deletion that uses a deleted_at field to track when a model instance is deleted. If that field is set, YORM considers the field "deleted".

class User extends Model {
  id
  deleted_at

  get softDeletes() { return true }
}

const user = await User.create()

await user.delete() // UPDATE users SET deleted_at = NOW() WHERE id = 1

We also provide a way of restoring soft-deleted model instances:

// If you already have a model instance, just call...
await user.restore()

// Typically, this won't be the case. For situations where you don't, use the static version:
await User.restore(query => query.where({ id: 1 }))

Lastly, we added a feature to "hide" select properties from the "toJSON" representation of an object. This can be useful when you're passing your models directly when making API responses (e.g. res.json(...) in Express).

If you define a hidden accessor on your model that returns an array of field names, they will automatically be omitted from JSON output.

class User extends Model {
  id
  username
  password

  get hidden() {
    return ['password']
  }
}

const user = User.make({ username: 'user', password: 'super.secret' })

JSON.stringify(user) // { "username": "user" }

You could always do this manually by overriding the model's toJSON method. For one-offs, this feature doesn't really add much, but it is a more declarative way of expressing sensitivity that's harder to overlook later down the road.