Skip to content

Instantly share code, notes, and snippets.

@chadwithuhc
Last active January 13, 2017 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chadwithuhc/d4d09151a0c364e92884cf1ebecefd57 to your computer and use it in GitHub Desktop.
Save chadwithuhc/d4d09151a0c364e92884cf1ebecefd57 to your computer and use it in GitHub Desktop.
ORMs Slides

ORM

Object Relational Mapper


Object ... We're working with objects (as in database rows)

Relational ... Specifically handling relational data

Mapper ... Mapping objects together for you


Objectives

  • Describe the features of an ORM
  • Define common ORM terms
  • Describe common use cases for an ORM
  • Describe what ORM code is doing

ORM Features

ORMs generally include:

  • Easy querying without writing SQL (a.k.a. Query Building)

    • .find(), .where(), .orderBy()
  • Extending functionality with hooks or events

    • Validations, attribute manipulations, computed properties, limited scopes
  • Relationship handling without JOINs

    • Mapping relationships in model definitions
    • Easily loading relationships through Query Building

ORM Terms

Model ... Single row or record

Collection ... Group of models

Query Building ... Chaining methods together to generate a SQL query

Eager Loading ... Loading relationships when querying


ORM Use Cases

  • You are using relational data in your database
  • You would like to abstract your SQL query creation
  • You need to create SQL queries on-the-fly
  • You are too lazy to write SQL

Deep Thought

  • When would an ORM not be useful?

Relationships

Types

  • One-to-one
  • One-to-many
  • Many-to-many

Rules

  • One items have singular names
  • Many items have plural names
  • Tables are always named plural

One-to-one

One-to-one Code


One-to-one

// Get a book with specific ISBN-13 number, including its summary
new Book({'ISBN-13': '9780440180296'})
  .fetch({
    withRelated: ['summary']
  })
  .then(function(book) {
    // 'Slaughterhouse Five'
    book.get('title')
    // Access to properties on "Summary" model
    book.related('summary')
  })

In this code:

  • Fetching a book by ISBN-13 number
  • Eager Loading the summary data
  • Accessing properties on book model
  • Accessing related summary model

One-to-many

One-to-many Code


One-to-many

// Get a book with specific ISBN-13 number, including its pages
new Book({'ISBN-13': '9780440180296'})
  .fetch({
    withRelated: ['pages']
  }).then(function(book) {
    // Collection of page models
    book.related('pages')
    // Only retrieve odd pages
    book.related('pages').filter(function(page) {
      return page.get('number') % 1
    })
  })

In this code:

  • Fetching a book by ISBN-13 number
  • Eager Loading the pages
  • Accessing related pages Collection
  • ??

One-to-many

// Get a book with specific ISBN-13 number, including its pages
new Book({'ISBN-13': '9780440180296'})
  .fetch({
    withRelated: ['pages']
  }).then(function(book) {
    // Collection of page models
    book.related('pages')
    // Only retrieve odd pages
    book.related('pages').filter(function(page) {
      return page.get('number') % 1
    })
  })

In this code:

  • Fetching a book by ISBN-13 number
  • Eager Loading the pages
  • Accessing related pages Collection
  • Filtering to only odd pages

Question

  • What is the following code doing?
Post.where({ id: 12345 }).fetch({
  withRelated: ['blog', 'author', 'comments']
}).then(function(post) {
  post.related('author').get('name')
  post.related('blog').get('title')
  post.related('comments').length
})

Many-to-many

Many-to-many Code


Many-to-many

// Get author info along with their books
Author.where({name: 'George Costanza'})
  .fetch({
    withRelated: ['books']
  }).then(function(author) {
    author.related('books').where({ year: 2017 })
  })

In this code:

  • Fetching an author by name
  • ??
  • ??

Many-to-many

// Get author info along with their books
Author.where({name: 'George Costanza'})
  .fetch({
    withRelated: ['books']
  }).then(function(author) {
    author.related('books').where({ year: 2017 })
  })

In this code:

  • Fetching an author by name
  • Eager Loading their books
  • ??

Many-to-many

// Get author info along with their books
Author.where({name: 'George Costanza'})
  .fetch({
    withRelated: ['books']
  }).then(function(author) {
    author.related('books').where({ year: 2017 })
  })

In this code:

  • Fetching an author by name
  • Eager Loading their books
  • Filtering their books down to releases this year

Question

  • What kind of relationship does the following code setup?
let Classroom = bookshelf.Model.extend({
  tableName: 'classrooms',
  students: function() {
    return this.hasMany(Student);
  }
});

let Student = bookshelf.Model.extend({
  tableName: 'students',
  classroom: function() {
    return this.belongsTo(Classroom);
  }
});

ORM Assessment

  • What does ORM stand for?
  • What are some common ORM features?
  • What is Eager Loading?

And finally ...


ORM Assessment

  • What is wrong with this code?
let Folders = bookshelf.Model.extend({
  tableName: 'folder',
  files: function() {
    return this.hasMany(File);
  }
});

let File = bookshelf.Model.extend({
  tableName: 'files',
  folders: function() {
    this.belongsTo(Folder);
  }
});
  • ??
  • ??
  • ??
  • ??

ORM Assessment

  • What is wrong with this code?
let Folders = bookshelf.Model.extend({
  tableName: 'folder',
  files: function() {
    return this.hasMany(File);
  }
});

let File = bookshelf.Model.extend({
  tableName: 'files',
  folders: function() {
    this.belongsTo(Folder);
  }
});
  • Folders model should be singular
  • ??
  • ??
  • ??

ORM Assessment

  • What is wrong with this code?
let Folders = bookshelf.Model.extend({
  tableName: 'folder',
  files: function() {
    return this.hasMany(File);
  }
});

let File = bookshelf.Model.extend({
  tableName: 'files',
  folders: function() {
    this.belongsTo(Folder);
  }
});
  • Folders model should be singular
  • Folder model should have plural table name
  • ??
  • ??

ORM Assessment

  • What is wrong with this code?
let Folders = bookshelf.Model.extend({
  tableName: 'folder',
  files: function() {
    return this.hasMany(File);
  }
});

let File = bookshelf.Model.extend({
  tableName: 'files',
  folders: function() {
    this.belongsTo(Folder);
  }
});
  • Folders model should be singular
  • Folder model should have plural table name
  • File model should have folder property (singular)
  • ??

ORM Assessment

  • What is wrong with this code?
let Folders = bookshelf.Model.extend({
  tableName: 'folder',
  files: function() {
    return this.hasMany(File);
  }
});

let File = bookshelf.Model.extend({
  tableName: 'files',
  folders: function() {
    this.belongsTo(Folder);
  }
});
  • Folders model should be singular
  • Folder model should have plural table name
  • File model should have folder property (singular)
  • return missing from File model

Objectives Complete!

  • Describe the features of an ORM
  • Define common ORM terms
  • Describe common use cases for an ORM
  • Describe what ORM code is doing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment