Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make require: true the default for Model#fetch #2006

Merged
merged 8 commits into from Aug 27, 2019

Conversation

@ricardograca
Copy link
Member

commented Aug 25, 2019

  • Related Issues: #718

Introduction

Make require: true the default for Model#fetch and Collection#fetchOne calls.

Motivation

When fetching a single model there is usually a precise set of constraints, so as a user I'm interested in getting that model, not any other value. This is especially true when logging in a user, or when looking for a specific record of something. Usually all further processing of said model should be skipped since it wouldn't make sense, so this facilitates that mechanism by default.

This change ensures that fetch calls like:

new MyModel({id: 1}).fetch()

will always resolve with a model, avoiding the need to additionally check if the result is not null. If the model cannot be fetched because it does not exist in the database an error will be thrown and the fetch call will be rejected with MyModel.NotFoundError. This specific error class can be caught and dealt with appropriately:

new MyModel({id: 1})
  .fetch()
  .then(myModel => {
    // do something with the fetched model
  })
  .catch(MyModel.NotFoundError, error => {
    // handle no results error
  })

Closes #718.

Proposed solution

This adds a new Model#requireFetch property that can be used to set the default behavior when handling empty responses of Model#fetch, and sets its default value to true, meaning that the default is to reject the fetch Promise.

The new model level property also means that users that prefer the previous behavior can easily adapt their code by simply adding requireFetch: false to their model definitions.

There is a migration guide in the Wiki to help with the transition to this new default.

Current PR Issues

This does not change the default behavior when fetching collections, mainly because it's not easy to catch an EmptyResponse error from a collection built from model methods like Model#fetchAll or Model#fetchPage. It can also be argued that when fetching collections, the requirements are not as strict, and it's usually OK for them to be empty.

Not everyone is going to like this change, but it should be relatively easy to keep using the previous behavior for those that prefer to think is terms of SQL and less about abstract higher level objects.

Alternatives considered

There are some commits in this series that actually made require: true the default also for fetching collections, unifying all fetch interfaces in terms of behavior, but it was proving very difficult (impossible?) to catch errors by a specific collection's EmptyResponse error.

@ricardograca ricardograca added the change label Aug 25, 2019
@ricardograca ricardograca changed the title Rg require fetch Make require: true the default for Model#fetch Aug 25, 2019
@ricardograca ricardograca merged commit 6076bd0 into master Aug 27, 2019
2 checks passed
2 checks passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
continuous-integration/travis-ci/push The Travis CI build passed
Details
@ricardograca ricardograca deleted the rg-require-fetch branch Aug 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.