js-data

Respect Your Data

Give your data the treatment it deserves with a framework-agnostic, datastore-agnostic JavaScript ORM built for ease of use and peace of mind. Works in Node.js and in the Browser.

Get Started

Active Record Pattern

Concepts

Active Record Pattern

The Active Record Pattern accomplishes similar goals as the Data Mapper Pattern, but with a slightly different implementation. While the Data Mapper Pattern calls for one Mapper instance per database view/table/collection, the Active Record Pattern wraps each database view/table/collection into a class, with instances of that class corresponding to individual "smart" records in each view/table/collection. These smart records are capable of saving and destroying themselves. JSData's default approach is a combination of the Data Mapper Pattern and the Active Record Pattern.

👍

Tip

While Mapper instances can work with POJOs, by default records will be wrapped in the Record class, turning them into "smart" records.

Here's are some quick examples to illustrate:

// or import {DataStore} from 'js-data'
import {Container} from 'js-data'
import adapter from './adapter.js'

// or const store = new DataStore()
const store = new Container()
store.registerAdapter('myadapter', adapter, { default: true })

// Mapper instance (Data Mapper Pattern)
store.defineMapper('post')

// Create and save a new post record using the Data Mapper Pattern
store.create('post', {
  title: 'Conceptual Overview of JSData'
}).then((post) => {
  console.log(post.id) // 1234

  // Create and save a new post record using the Active Record Pattern
  const post = store.createRecord('post', {
    title: 'Components of JSData'
  })
  return post.save()
}).then((post) => {
  console.log(post.id) // 1235
})
// or import {DataStore} from 'js-data'
import {Container} from 'js-data'
import adapter from './adapter.js'

// or const store = new DataStore()
const store = new Container()
store.registerAdapter('myadapter', adapter, { default: true })

// Mapper instance (Data Mapper Pattern)
store.defineMapper('post')

// Update a post record using the Data Mapper Pattern
store.update('post', 1234, {
  status: 'published'
}).then((post) => {
  console.log(post.id) // 1234
  console.log(post.status) // "published"
  console.log(post.published_at) // undefined

  // Update a post record using the Active Record Pattern
  post.published_at = new Date()
  return post.save()
}).then((post) => {
  console.log(post.id) // 1234
  console.log(post.status) // "published"
  console.log(post.published_at) // "2016-04-18T15:20:53.949Z"
})
// or import {DataStore} from 'js-data'
import {Container} from 'js-data'
import adapter from './adapter.js'

// or const store = new DataStore()
const store = new Container()
store.registerAdapter('myadapter', adapter, { default: true })

// Mapper instance (Data Mapper Pattern)
store.defineMapper('post')

// Destroy post record using the Data Mapper Pattern
store.destroy('post', 1234).then(() => {

  // Destroy a post record using the Active Record Pattern
  const post = store.createRecord('post', {
    id: 3554
  })
  // post with id 3554 is destroyed from the database
  return post.destroy()
})

Some folks like the convenience of smart records, because as they pass record instances around in their application they can easily create, update, and delete records without turning to a Mapper instance.

One tradeoff to "smart" records is that the extra behavior provided by the class interface takes up property names that you might otherwise use as your column names.

Updated 4 years ago


Active Record Pattern


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.