Feathers: Service.create fehlschlagen/verbieten, wenn service.get(id) bereits existiert

Erstellt am 23. Juni 2017  ·  4Kommentare  ·  Quelle: feathersjs/feathers

Ich habe erwartet, dass service.create(obj) fehlschlägt, wenn bereits ein vorhandener Eintrag mit demselben id in der Datenbank existiert. Ich bin mir nicht sicher, ob dies im Bereich von Federn, der spezifischen Datenbankdienstschnittstelle (hier Federn-nedb) oder Federn-Hooks-Common liegt.

Schritte zum Reproduzieren

const feathers = require('feathers');
const NeDB = require('nedb');
const service = require('feathers-nedb');

const app = feathers()
app.use('/users', service({ Model: userModel(), id: 'email' }));

const users = app.service('/users');
let user = { email: '[email protected]', password: '11111', role: 'admin' }
Promise.all([
  users.create(user),
  users.create(user)
]).then(results => console.log(results))
  .catch(err => console.log('Error occurred:', err));

function userModel() {
  return new NeDB({
    filename: 'users.db',
    autoload: true
  });
}

Erwartetes Verhalten

Ich hatte erwartet, dass das zweite users.create scheitern würde.

Tatsächliches Verhalten

Derselbe Benutzer wird zweimal zur Datenbank hinzugefügt.

Vorgeschlagener Haken

const { validate } = require('feathers-hooks-common')

/**
 * Checks if item with same id already exists.
 */
module.exports = function unique () {
  return validate((values, hook) => {
    return hook.service.get(values[hook.service.id])
      .catch(() => null)  // not found, pass null to next .then
      .then(res => res === null
        ? null
        : Promise.reject(new Error(`${res[hook.service.id]} already exists in db`)))
  })
}

Hilfreichster Kommentar

Danke für die Hilfe. Hier ist die Lösung für andere, die darüber stolpern:

function userModel() {
  let Model = new NeDB({
    filename: 'users.db',
    autoload: true
  });

  Model.ensureIndex({ fieldName: 'email', unique: true }, err => {
    if (err) throw err
  });

  return Model;
}

Alle 4 Kommentare

Abgesehen von Hooks gibt es ein häufig übersehenes Problem mit Ihrem Hook, den param . Beispielsweise werden mit get keine Authentifizierungsinformationen übergeben. Sehen Sie, wie der Hook stashBefore umgeht.

Dies ist ein Problem, das im Allgemeinen aus Effizienzgründen von der Datenbank behandelt werden sollte. Es ist definitiv möglich, als Hook zu implementieren, aber es wird nicht annähernd so effizient sein wie die Verwendung von NeDB Unique Constraint-Indizes: https://github.com/louischatriot/nedb/wiki/Indexing

Danke für die Hilfe. Hier ist die Lösung für andere, die darüber stolpern:

function userModel() {
  let Model = new NeDB({
    filename: 'users.db',
    autoload: true
  });

  Model.ensureIndex({ fieldName: 'email', unique: true }, err => {
    if (err) throw err
  });

  return Model;
}

Dieses Problem wurde automatisch gesperrt, da es nach dem Schließen in letzter Zeit keine Aktivität gab. Bitte öffnen Sie eine neue Ausgabe mit einem Link zu dieser Ausgabe für verwandte Fehler.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen