JSORM the isomorphic, framework-agnostic Javascript ORM

Nested Queries

We can nest all read operations at any level of the graph. Let’s say we wanted to fetch all Posts and their Comments…but only return comments that are active, sorted by created_at descending. We can create a Comment scope as normal, then #merge() it into our Post scope:

Typescript
Javascript
let commentScope = Comment
  .where({ active: true })
  .order({ created_at: "desc" })
Post
  .includes("comments")
  .merge({ comments: commentScope })
  .all()
var commentScope = Comment
  .where({ active: true })
  .order({ created_at: "desc" })
Post
  .includes("comments")
  .merge({ comments: commentScope })
  .all()

/posts?include=comments&filter[comments][active]=true&sort=-comments.active

Because this can get verbose, it’s often desirable to store it on the class:

Typescript
Javascript
class Comment extends ApplicationRecord {
  // ... code ...
  static recent() {
    return this
      .where({ active: true })
      .order({ created_at: "desc" })
  }
}

Post.merge({ comments: Comment.recent() }).all()
const Comment = ApplicationRecord.extend({
  // ... code ...
  static: {
    recent: function() {
      return this
        .where({ active: true })
        .order({ created_at: "desc" })
    }
  }
})

Post
  .includes("comments")
  .merge({ comments: Comment.recent() })
  .all()

Any number of scopes can be merged in. Just remember to #include() and #merge() relationship names as the server understands them:

Typescript
Javascript
class Dog extends ApplicationRecord {
  @BelongsTo() person: Person
}

// We've modeled this as Dog > person in javascript
// And Person is jsonapiType "people"
// But the server defined the relationship as "owner"
Dog.includes("owner").merge({ owner: Person.limitedFields() })
const Dog = ApplicationRecord.extend({
  // ... code ...
  methods: {
    person: belongsTo()
  }
})

// We've modeled this as Dog > person in javascript
// And Person is jsonapiType "people"
// But the server defined the relationship as "owner"
Dog.includes("owner").merge({ owner: Person.limitedFields() })