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
Merged

Conversation

ricardograca
Copy link
Member

@ricardograca ricardograca commented Aug 25, 2019

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 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
@ricardograca ricardograca deleted the rg-require-fetch branch August 27, 2019 20:00
@dtturcotte
Copy link

dtturcotte commented Jul 17, 2024

This is not a good change. You're making quite an assumption for use cases. What if I wanted to check if a value exists (e.g., I'm searching by string for a dictionary entry... if it's not there, oh well!). You should leave it to the developer to decide what they want to do if the value is not there. I upgraded recently from 0.13 to 1.0 and this broke many things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Provide an option to use { require: true } as default in model.fetch
2 participants